-
Notifications
You must be signed in to change notification settings - Fork 0
/
json_builder.cpp
101 lines (89 loc) · 3.36 KB
/
json_builder.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "json_builder.h"
namespace json {
using namespace std::literals;
Builder::DictValueContext Builder::Key(std::string key) {
if (root_.IsNull() || (!nodes_stack_.empty() && !nodes_stack_.back()->IsDict())) {
throw std::logic_error("Incorrect Dict key insertion"s);
}
if (IsSingleValueRoot()) {
throw std::logic_error("Incorrect Dict key insertion"s);
}
is_key_ = true;
json::Node* value_ptr_ = &std::get<json::Dict>(nodes_stack_.back()->GetValue())[std::move(key)];
nodes_stack_.push_back(value_ptr_);
return BaseContext(*this);
}
Builder::BaseContext Builder::Value(json::Value value) {
if (IsSingleValueRoot()) {
throw std::logic_error("Multivalued node must be Array or Dict. Cannot insert value"s);
}
if (NotAKeyValue()) {
throw std::logic_error("Trying to assign value to Dict with no key associated"s);
}
if (root_.IsNull() && nodes_stack_.empty()) {
root_.GetValue() = std::move(value);
} else if (nodes_stack_.back()->IsNull() && is_key_) {
is_key_ = false;
nodes_stack_.back()->GetValue() = std::move(value);
nodes_stack_.pop_back();
} else if (!nodes_stack_.empty() && nodes_stack_.back()->IsArray()) {
std::get<json::Array>(nodes_stack_.back()->GetValue()).emplace_back(std::move(value));
}
return BaseContext(*this);
}
Builder::ArrayItemContext Builder::StartArray() {
if (IsSingleValueRoot()) {
throw std::logic_error("Multivalued node must be Array or Dict. Cannot start Array"s);
}
if (NotAKeyValue()) {
throw std::logic_error("Trying to assign Array to Dict with no key associated"s);
}
StartContainer<json::Array>();
return BaseContext(*this);
}
Builder::DictItemContext Builder::StartDict() {
if (IsSingleValueRoot()) {
throw std::logic_error("Multivalued node must be Array or Dict. Cannot start Dict"s);
}
if (NotAKeyValue()) {
throw std::logic_error("Trying to assign Dict to Dict with no key associated"s);
}
StartContainer<json::Dict>();
return BaseContext(*this);
}
Builder::BaseContext Builder::EndArray() {
if (root_.IsNull() || (!nodes_stack_.empty() && !nodes_stack_.back()->IsArray())) {
throw std::logic_error("Trying to close incomplete sequence or no Array start found"s);
}
if (IsSingleValueRoot()) {
throw std::logic_error("Trying to close incomplete sequence or no Array start found"s);
}
nodes_stack_.pop_back();
return BaseContext(*this);
}
Builder::BaseContext Builder::EndDict() {
if (root_.IsNull() || (!nodes_stack_.empty() && !nodes_stack_.back()->IsDict())) {
throw std::logic_error("Trying to close incomplete sequence or no Dict start found"s);
}
if (IsSingleValueRoot()) {
throw std::logic_error("Trying to close incomplete sequence or no Dict start found"s);
}
nodes_stack_.pop_back();
return BaseContext(*this);
}
json::Node Builder::Build() {
if (root_.IsNull()) {
throw std::logic_error("Cannot build empty root"s);
}
if (!nodes_stack_.empty()) {
throw std::logic_error("Cannot build incomplete sequence"s);
}
return root_;
}
bool Builder::IsSingleValueRoot() {
return !root_.IsNull() && nodes_stack_.empty();
}
bool Builder::NotAKeyValue() {
return !nodes_stack_.empty() && nodes_stack_.back()->IsDict();
}
} // namespace json