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)
15 : value_parser_(value_parser)
16 {}
17
18 void Reset() override { this->state_ = State::kStart; }
19
20 void StartObject() override {
21 switch (state_) {
22 case State::kStart:
23 this->state_ = State::kInside;
24 break;
25
26 case State::kInside:
27 this->Throw("{");
28 }
29 }
30
31 void Key(std::string_view key) override {
32 if (state_ != State::kInside) {
33 this->Throw("object");
34 }
35
36 key_ = key;
37 this->value_parser_.Reset();
38 this->value_parser_.Subscribe(*this);
39 this->parser_state_->PushParser(this->value_parser_.GetParser());
40 }
41
42 void EndObject() override {
43 if (state_ == State::kInside) {
44 this->SetResult(std::move(result_));
45 return;
46 }
47 // impossible?
48 this->Throw("}");
49 }
50
51 std::string Expected() const override {
52 switch (state_) {
53 case State::kInside:
54 return "string";
55
56 case State::kStart:
57 return "object";
58 }
59
60 UINVARIANT(false, "Unexpected parser state");
61 }
62
63private:
64 void OnSend(Value&& value) override { this->result_.emplace(std::move(key_), std::move(value)); }
65
66 std::string GetPathItem() const override { return key_; }
67
68 enum class State {
69 kStart,
70 kInside,
71 };
72 State state_;
73 std::string key_;
74 Map result_;
75 ValueParser& value_parser_;
76};
77
78} // namespace formats::json::parser
79
80USERVER_NAMESPACE_END