userver: userver/formats/json/parser/map_parser.hpp Source File
Loading...
Searching...
No Matches
map_parser.hpp
1#pragma once
2
3#include <userver/formats/json/parser/typed_parser.hpp>
4
5USERVER_NAMESPACE_BEGIN
6
7namespace formats::json::parser {
8
9template <typename Map, typename ValueParser>
10class MapParser final : public TypedParser<Map>, public Subscriber<typename Map::mapped_type> {
11public:
12 using Value = typename Map::mapped_type;
13
14 explicit MapParser(ValueParser& value_parser) : value_parser_(value_parser) {}
15
16 void Reset() override { this->state_ = State::kStart; }
17
18 void StartObject() override {
19 switch (state_) {
20 case State::kStart:
21 this->state_ = State::kInside;
22 break;
23
24 case State::kInside:
25 this->Throw("{");
26 }
27 }
28
29 void Key(std::string_view key) override {
30 if (state_ != State::kInside) this->Throw("object");
31
32 key_ = key;
33 this->value_parser_.Reset();
34 this->value_parser_.Subscribe(*this);
35 this->parser_state_->PushParser(this->value_parser_.GetParser());
36 }
37
38 void EndObject() override {
39 if (state_ == State::kInside) {
40 this->SetResult(std::move(result_));
41 return;
42 }
43 // impossible?
44 this->Throw("}");
45 }
46
47 std::string Expected() const override {
48 switch (state_) {
49 case State::kInside:
50 return "string";
51
52 case State::kStart:
53 return "object";
54 }
55
56 UINVARIANT(false, "Unexpected parser state");
57 }
58
59private:
60 void OnSend(Value&& value) override { this->result_.emplace(std::move(key_), std::move(value)); }
61
62 std::string GetPathItem() const override { return key_; }
63
64 enum class State {
65 kStart,
66 kInside,
67 };
68 State state_;
69 std::string key_;
70 Map result_;
71 ValueParser& value_parser_;
72};
73
74} // namespace formats::json::parser
75
76USERVER_NAMESPACE_END