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