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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#pragma once
#include <list>
#include "StarJson.hpp"
namespace Star {
STAR_CLASS(FormattedJson);
struct ObjectElement;
struct ObjectKeyElement;
struct ValueElement;
struct WhitespaceElement;
struct ColonElement;
struct CommaElement;
typedef Variant<ValueElement, ObjectKeyElement, WhitespaceElement, ColonElement, CommaElement> JsonElement;
struct ValueElement {
ValueElement(FormattedJson const& json);
FormattedJsonPtr value;
bool operator==(ValueElement const& v) const;
};
struct ObjectKeyElement {
String key;
bool operator==(ObjectKeyElement const& v) const;
};
struct WhitespaceElement {
String whitespace;
bool operator==(WhitespaceElement const& v) const;
};
struct ColonElement {
bool operator==(ColonElement const&) const;
};
struct CommaElement {
bool operator==(CommaElement const&) const;
};
std::ostream& operator<<(std::ostream& os, JsonElement const& elem);
// Class representing formatted JSON data. Preserves whitespace and comments.
class FormattedJson {
public:
typedef List<JsonElement> ElementList;
typedef size_t ElementLocation;
static FormattedJson parse(String const& string);
static FormattedJson parseJson(String const& string);
static FormattedJson ofType(Json::Type type);
FormattedJson();
FormattedJson(Json const&);
Json const& toJson() const;
FormattedJson get(String const& key) const;
FormattedJson get(size_t index) const;
// Returns a new FormattedJson with the given values added or erased.
// Prepend, insert and append update the value in-place if the key already
// exists.
FormattedJson prepend(String const& key, FormattedJson const& value) const;
FormattedJson insertBefore(String const& key, FormattedJson const& value, String const& beforeKey) const;
FormattedJson insertAfter(String const& key, FormattedJson const& value, String const& afterKey) const;
FormattedJson append(String const& key, FormattedJson const& value) const;
FormattedJson set(String const& key, FormattedJson const& value) const;
FormattedJson eraseKey(String const& key) const;
FormattedJson insert(size_t index, FormattedJson const& value) const;
FormattedJson append(FormattedJson const& value) const;
FormattedJson set(size_t index, FormattedJson const& value) const;
FormattedJson eraseIndex(size_t index) const;
// Returns the number of elements in a Json array, or entries in an object.
size_t size() const;
bool contains(String const& key) const;
Json::Type type() const;
bool isType(Json::Type type) const;
String typeName() const;
String toFormattedDouble() const;
String toFormattedInt() const;
String repr() const;
String printJson() const;
ElementList const& elements() const;
// Equality ignores whitespace and formatting. It just compares the Json
// values.
bool operator==(FormattedJson const& v) const;
bool operator!=(FormattedJson const& v) const;
private:
friend class FormattedJsonBuilderStream;
static FormattedJson object(ElementList const& elements);
static FormattedJson array(ElementList const& elements);
FormattedJson objectInsert(String const& key, FormattedJson const& value, ElementLocation loc) const;
void appendElement(JsonElement const& elem);
FormattedJson const& getFormattedJson(ElementLocation loc) const;
FormattedJson formattedAs(String const& formatting) const;
Json m_jsonValue;
ElementList m_elements;
// Used to preserve the formatting of numbers, i.e. -0 vs 0, 1.0 vs 1:
Maybe<String> m_formatting;
Maybe<ElementLocation> m_lastKey, m_lastValue;
Map<String, pair<ElementLocation, ElementLocation>> m_objectEntryLocations;
List<ElementLocation> m_arrayElementLocations;
};
std::ostream& operator<<(std::ostream& os, FormattedJson const& json);
}
template <> struct fmt::formatter<Star::FormattedJson> : ostream_formatter {};
|