Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/Analysis/include/Luau/JsonEmitter.h
2727 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#pragma once
3
4
#include <type_traits>
5
#include <string>
6
#include <optional>
7
#include <unordered_map>
8
#include <vector>
9
10
#include "Luau/NotNull.h"
11
12
namespace Luau::Json
13
{
14
15
struct JsonEmitter;
16
17
/// Writes a value to the JsonEmitter. Note that this can produce invalid JSON
18
/// if you do not insert commas or appropriate object / array syntax.
19
template<typename T>
20
void write(JsonEmitter&, T) = delete;
21
22
/// Writes a boolean to a JsonEmitter.
23
/// @param emitter the emitter to write to.
24
/// @param b the boolean to write.
25
void write(JsonEmitter& emitter, bool b);
26
27
/// Writes an integer to a JsonEmitter.
28
/// @param emitter the emitter to write to.
29
/// @param i the integer to write.
30
void write(JsonEmitter& emitter, int i);
31
32
/// Writes an integer to a JsonEmitter.
33
/// @param emitter the emitter to write to.
34
/// @param i the integer to write.
35
void write(JsonEmitter& emitter, long i);
36
37
/// Writes an integer to a JsonEmitter.
38
/// @param emitter the emitter to write to.
39
/// @param i the integer to write.
40
void write(JsonEmitter& emitter, long long i);
41
42
/// Writes an integer to a JsonEmitter.
43
/// @param emitter the emitter to write to.
44
/// @param i the integer to write.
45
void write(JsonEmitter& emitter, unsigned int i);
46
47
/// Writes an integer to a JsonEmitter.
48
/// @param emitter the emitter to write to.
49
/// @param i the integer to write.
50
void write(JsonEmitter& emitter, unsigned long i);
51
52
/// Writes an integer to a JsonEmitter.
53
/// @param emitter the emitter to write to.
54
/// @param i the integer to write.
55
void write(JsonEmitter& emitter, unsigned long long i);
56
57
/// Writes a double to a JsonEmitter.
58
/// @param emitter the emitter to write to.
59
/// @param d the double to write.
60
void write(JsonEmitter& emitter, double d);
61
62
/// Writes a string to a JsonEmitter. The string will be escaped.
63
/// @param emitter the emitter to write to.
64
/// @param sv the string to write.
65
void write(JsonEmitter& emitter, std::string_view sv);
66
67
/// Writes a character to a JsonEmitter as a single-character string. The
68
/// character will be escaped.
69
/// @param emitter the emitter to write to.
70
/// @param c the string to write.
71
void write(JsonEmitter& emitter, char c);
72
73
/// Writes a string to a JsonEmitter. The string will be escaped.
74
/// @param emitter the emitter to write to.
75
/// @param str the string to write.
76
void write(JsonEmitter& emitter, const char* str);
77
78
/// Writes a string to a JsonEmitter. The string will be escaped.
79
/// @param emitter the emitter to write to.
80
/// @param str the string to write.
81
void write(JsonEmitter& emitter, const std::string& str);
82
83
/// Writes null to a JsonEmitter.
84
/// @param emitter the emitter to write to.
85
void write(JsonEmitter& emitter, std::nullptr_t);
86
87
/// Writes null to a JsonEmitter.
88
/// @param emitter the emitter to write to.
89
void write(JsonEmitter& emitter, std::nullopt_t);
90
91
struct ObjectEmitter;
92
struct ArrayEmitter;
93
94
struct JsonEmitter
95
{
96
JsonEmitter();
97
98
/// Converts the current contents of the JsonEmitter to a string value. This
99
/// does not invalidate the emitter, but it does not clear it either.
100
std::string str();
101
102
/// Returns the current comma state and resets it to false. Use popComma to
103
/// restore the old state.
104
/// @returns the previous comma state.
105
bool pushComma();
106
107
/// Restores a previous comma state.
108
/// @param c the comma state to restore.
109
void popComma(bool c);
110
111
/// Writes a raw sequence of characters to the buffer, without escaping or
112
/// other processing.
113
/// @param sv the character sequence to write.
114
void writeRaw(std::string_view sv);
115
116
/// Writes a character to the buffer, without escaping or other processing.
117
/// @param c the character to write.
118
void writeRaw(char c);
119
120
/// Writes a comma if this wasn't the first time writeComma has been
121
/// invoked. Otherwise, sets the comma state to true.
122
/// @see pushComma
123
/// @see popComma
124
void writeComma();
125
126
/// Begins writing an object to the emitter.
127
/// @returns an ObjectEmitter that can be used to write key-value pairs.
128
ObjectEmitter writeObject();
129
130
/// Begins writing an array to the emitter.
131
/// @returns an ArrayEmitter that can be used to write values.
132
ArrayEmitter writeArray();
133
134
private:
135
bool comma = false;
136
std::vector<std::string> chunks;
137
138
void newChunk();
139
};
140
141
/// An interface for writing an object into a JsonEmitter instance.
142
/// @see JsonEmitter::writeObject
143
struct ObjectEmitter
144
{
145
ObjectEmitter(NotNull<JsonEmitter> emitter);
146
~ObjectEmitter();
147
148
NotNull<JsonEmitter> emitter;
149
bool comma;
150
bool finished;
151
152
/// Writes a key-value pair to the associated JsonEmitter. Keys will be escaped.
153
/// @param name the name of the key-value pair.
154
/// @param value the value to write.
155
template<typename T>
156
void writePair(std::string_view name, T value)
157
{
158
if (finished)
159
{
160
return;
161
}
162
163
emitter->writeComma();
164
write(*emitter, name);
165
emitter->writeRaw(':');
166
write(*emitter, value);
167
}
168
169
/// Finishes writing the object, appending a closing `}` character and
170
/// resetting the comma state of the associated emitter. This can only be
171
/// called once, and once called will render the emitter unusable. This
172
/// method is also called when the ObjectEmitter is destructed.
173
void finish();
174
};
175
176
/// An interface for writing an array into a JsonEmitter instance. Array values
177
/// do not need to be the same type.
178
/// @see JsonEmitter::writeArray
179
struct ArrayEmitter
180
{
181
ArrayEmitter(NotNull<JsonEmitter> emitter);
182
~ArrayEmitter();
183
184
NotNull<JsonEmitter> emitter;
185
bool comma;
186
bool finished;
187
188
/// Writes a value to the array.
189
/// @param value the value to write.
190
template<typename T>
191
void writeValue(T value)
192
{
193
if (finished)
194
{
195
return;
196
}
197
198
emitter->writeComma();
199
write(*emitter, value);
200
}
201
202
/// Finishes writing the object, appending a closing `]` character and
203
/// resetting the comma state of the associated emitter. This can only be
204
/// called once, and once called will render the emitter unusable. This
205
/// method is also called when the ArrayEmitter is destructed.
206
void finish();
207
};
208
209
/// Writes a vector as an array to a JsonEmitter.
210
/// @param emitter the emitter to write to.
211
/// @param vec the vector to write.
212
template<typename T>
213
void write(JsonEmitter& emitter, const std::vector<T>& vec)
214
{
215
ArrayEmitter a = emitter.writeArray();
216
217
for (const T& value : vec)
218
a.writeValue(value);
219
220
a.finish();
221
}
222
223
/// Writes an optional to a JsonEmitter. Will write the contained value, if
224
/// present, or null, if no value is present.
225
/// @param emitter the emitter to write to.
226
/// @param v the value to write.
227
template<typename T>
228
void write(JsonEmitter& emitter, const std::optional<T>& v)
229
{
230
if (v.has_value())
231
write(emitter, *v);
232
else
233
emitter.writeRaw("null");
234
}
235
236
template<typename T>
237
void write(JsonEmitter& emitter, const std::unordered_map<std::string, T>& map)
238
{
239
ObjectEmitter o = emitter.writeObject();
240
241
for (const auto& [k, v] : map)
242
o.writePair(k, v);
243
244
o.finish();
245
}
246
247
} // namespace Luau::Json
248
249