std::pair parseKeyAccess()

in extensions/standard-processors/utils/JoltUtils.cpp [320:423]


std::pair<size_t, size_t> parseKeyAccess(std::string_view str) {
  enum class State {
    Begin,
    BeginRef,
    PrimaryIndex,
    BeginFirstIndex,
    FirstIndex,
    BeginSecondIndex,
    SecondIndex,
    End
  } state = State::Begin;
  std::string target;
  std::pair<size_t, size_t> result{0, 0};
  for (size_t idx = 0; idx <= str.size(); ++idx) {
    std::optional<char> ch;
    if (idx < str.size()) {
      ch = str[idx];
    }
    switch (state) {
      case State::Begin: {
        if (ch != '$') {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Expected '$' in key access in '{}' at {}", str, idx));
        }
        state = State::BeginRef;
        break;
      }
      case State::BeginRef: {
        if (ch == '(') {
          state = State::BeginFirstIndex;
        } else if (ch && std::isdigit(static_cast<unsigned char>(ch.value()))) {
          target.clear();
          target += ch.value();
          state = State::PrimaryIndex;
        } else if (ch) {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Expected index in key access in '{}' at {}", str, idx));
        }
        break;
      }
      case State::PrimaryIndex: {
        if (!ch) {
          result.first = std::stoull(target);
        } else if (std::isdigit(static_cast<unsigned char>(ch.value()))) {
          target += ch.value();
        } else {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Expected digit in key access in '{}' at {}", str, idx));
        }
        break;
      }
      case State::BeginFirstIndex: {
        if (!ch) {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Unterminated first index in key access in '{}'", str));
        } else if (std::isdigit(static_cast<unsigned char>(ch.value()))) {
          target.clear();
          target += ch.value();
          state = State::FirstIndex;
        } else {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Expected digit in key access in '{}' at {}", str, idx));
        }
        break;
      }
      case State::FirstIndex: {
        if (!ch) {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Unterminated first index in key access in '{}'", str));
        } else if (std::isdigit(static_cast<unsigned char>(ch.value()))) {
          target += ch.value();
        } else if (ch == ',') {
          result.first = std::stoull(target);
          state = State::BeginSecondIndex;
        }
        break;
      }
      case State::BeginSecondIndex: {
        if (!ch) {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Unterminated second index in key access in '{}'", str));
        } else if (std::isdigit(static_cast<unsigned char>(ch.value()))) {
          target.clear();
          target += ch.value();
          state = State::SecondIndex;
        } else {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Expected digit in key access in '{}' at {}", str, idx));
        }
        break;
      }
      case State::SecondIndex: {
        if (!ch) {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Unterminated second index in key access in '{}'", str));
        } else if (std::isdigit(static_cast<unsigned char>(ch.value()))) {
          target += ch.value();
        } else if (ch == ')') {
          result.second = std::stoull(target);
          state = State::End;
        }
        break;
      }
      case State::End: {
        if (ch) {
          throw Exception(GENERAL_EXCEPTION, fmt::format("Expected end of string in '{}' at {}", str, idx));
        }
        break;
      }
    }
  }
  return result;
}