Remove state from Extractor. It's usually a bad idea that bites us in the future, it did.

This commit is contained in:
Arthur Passos 2023-01-10 16:36:32 -03:00
parent 89ece4ab6d
commit 65188a565f
6 changed files with 28 additions and 40 deletions

View File

@ -34,13 +34,18 @@ public:
[[nodiscard]] Response extract(const std::string & file) override
{
std::unordered_map<std::string_view, std::string_view> response_views;
auto state = State::WAITING_KEY;
std::size_t pos = 0;
std::string_view key;
std::string_view value;
while (state != State::END)
{
auto next_state = processState(file, pos, state);
auto next_state = processState(file, pos, state, key, value, response_views);
pos = next_state.position_in_string;
state = next_state.state;
@ -50,36 +55,39 @@ public:
}
private:
NextState processState(const std::string & file, std::size_t pos, State state)
NextState processState(const std::string & file, std::size_t pos, State state,
std::string_view & key, std::string_view & value,
std::unordered_map<std::string_view, std::string_view> & response_views)
{
switch (state)
{
case State::WAITING_KEY:
return key_state_handler.wait(file, pos);
case State::READING_KEY:
return key_state_handler.read(file, pos);
return key_state_handler.read(file, pos, key);
case State::READING_ENCLOSED_KEY:
return key_state_handler.readEnclosed(file, pos);
return key_state_handler.readEnclosed(file, pos, key);
case State::READING_KV_DELIMITER:
return key_state_handler.readKeyValueDelimiter(file, pos);
case State::WAITING_VALUE:
return value_state_handler.wait(file, pos);
case State::READING_VALUE:
return value_state_handler.read(file, pos);
return value_state_handler.read(file, pos, value);
case State::READING_ENCLOSED_VALUE:
return value_state_handler.readEnclosed(file, pos);
return value_state_handler.readEnclosed(file, pos, value);
case State::READING_EMPTY_VALUE:
return value_state_handler.readEmpty(file, pos);
return value_state_handler.readEmpty(file, pos, value);
case State::FLUSH_PAIR:
return flushPair(file, pos);
return flushPair(file, pos, key, value, response_views);
case END:
return {pos, state};
}
}
NextState flushPair(const std::string & file, std::size_t pos)
NextState flushPair(const std::string & file, std::size_t pos, std::string_view key,
std::string_view value, std::unordered_map<std::string_view, std::string_view> & response_views)
{
response_views[key_state_handler.getElement()] = value_state_handler.getElement();
response_views[key] = value;
return {pos, pos == file.size() ? State::END : State::WAITING_KEY};
}
@ -87,8 +95,6 @@ private:
KeyStateHandler key_state_handler;
ValueStateHandler value_state_handler;
std::shared_ptr<KeyValuePairEscapingProcessor<Response>> escaping_processor;
std::unordered_map<std::string_view, std::string_view> response_views;
};
}

View File

@ -30,7 +30,7 @@ NextState KeyStateHandler::wait(const std::string & file, size_t pos) const
return {pos, State::END};
}
NextState KeyStateHandler::read(const std::string & file, size_t pos)
NextState KeyStateHandler::read(const std::string & file, size_t pos, std::string_view & key)
{
bool escape = false;
@ -65,7 +65,7 @@ NextState KeyStateHandler::read(const std::string & file, size_t pos)
return {pos, State::END};
}
NextState KeyStateHandler::readEnclosed(const std::string & file, size_t pos)
NextState KeyStateHandler::readEnclosed(const std::string & file, size_t pos, std::string_view & key)
{
auto start_index = pos;
key = {};
@ -104,9 +104,4 @@ NextState KeyStateHandler::readKeyValueDelimiter(const std::string & file, size_
}
}
std::string_view KeyStateHandler::getElement() const
{
return key;
}
}

View File

@ -15,15 +15,12 @@ public:
KeyStateHandler(char key_value_delimiter, char escape_character, std::optional<char> enclosing_character);
[[nodiscard]] NextState wait(const std::string & file, size_t pos) const;
[[nodiscard]] NextState read(const std::string & file, size_t pos);
[[nodiscard]] NextState readEnclosed(const std::string & file, size_t pos);
[[nodiscard]] NextState read(const std::string & file, size_t pos, std::string_view & key);
[[nodiscard]] NextState readEnclosed(const std::string & file, size_t pos, std::string_view & key);
[[nodiscard]] NextState readKeyValueDelimiter(const std::string & file, size_t pos) const;
[[nodiscard]] std::string_view getElement() const override;
private:
const char key_value_delimiter;
std::string_view key;
};
}

View File

@ -16,8 +16,6 @@ struct StateHandler
const char escape_character = '\\';
const std::optional<char> enclosing_character;
[[nodiscard]] virtual std::string_view getElement() const = 0;
protected:
[[nodiscard]] static std::string_view createElement(const std::string & file, std::size_t begin, std::size_t end);
};

View File

@ -41,7 +41,7 @@ NextState ValueStateHandler::wait(const std::string & file, size_t pos) const
return {pos, State::READING_EMPTY_VALUE};
}
NextState ValueStateHandler::read(const std::string & file, size_t pos)
NextState ValueStateHandler::read(const std::string & file, size_t pos, std::string_view & value)
{
bool escape = false;
@ -73,7 +73,7 @@ NextState ValueStateHandler::read(const std::string & file, size_t pos)
return {pos, State::FLUSH_PAIR};
}
NextState ValueStateHandler::readEnclosed(const std::string & file, size_t pos)
NextState ValueStateHandler::readEnclosed(const std::string & file, size_t pos, std::string_view & value)
{
auto start_index = pos;
@ -92,7 +92,7 @@ NextState ValueStateHandler::readEnclosed(const std::string & file, size_t pos)
return {pos, State::END};
}
NextState ValueStateHandler::readEmpty(const std::string &, size_t pos)
NextState ValueStateHandler::readEmpty(const std::string &, size_t pos, std::string_view & value)
{
value = {};
return {pos + 1, State::FLUSH_PAIR};
@ -103,9 +103,4 @@ bool ValueStateHandler::isValidCharacter(char character) const
return special_character_allowlist.contains(character) || std::isalnum(character) || character == '_';
}
std::string_view ValueStateHandler::getElement() const
{
return value;
}
}

View File

@ -19,16 +19,13 @@ public:
std::unordered_set<char> special_character_allowlist_);
[[nodiscard]] NextState wait(const std::string & file, size_t pos) const;
[[nodiscard]] NextState read(const std::string & file, size_t pos);
[[nodiscard]] NextState readEnclosed(const std::string & file, size_t pos);
[[nodiscard]] NextState readEmpty(const std::string & file, size_t pos);
[[nodiscard]] std::string_view getElement() const override;
[[nodiscard]] NextState read(const std::string & file, size_t pos, std::string_view & value);
[[nodiscard]] NextState readEnclosed(const std::string & file, size_t pos, std::string_view & value);
[[nodiscard]] static NextState readEmpty(const std::string & file, size_t pos, std::string_view & value);
private:
const char item_delimiter;
std::unordered_set<char> special_character_allowlist;
std::string_view value;
bool isValidCharacter(char character) const;
};