Skip to content

Commit 83f2524

Browse files
committed
FIX | json & bigint bugs
1 parent f1323f3 commit 83f2524

File tree

8 files changed

+602
-62
lines changed

8 files changed

+602
-62
lines changed
Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
---
2+
title: JSON
3+
description: JSON Support in ManapiHttp
4+
---
5+
6+
# JSON in C++
7+
By default, C++ does not have built-in JSON support.
8+
To address this, ManapiHttp provides a JSON implementation in the ```<manapihttp/json/ManapiJson.hpp>``` header file.
9+
10+
<Callout title="Warning" type="warn">
11+
Currently, JSON parsing may be slow in some cases.
12+
</Callout>
13+
14+
## Initialization
15+
16+
There are two ways to create JSON objects:
17+
- From text:
18+
```cpp
19+
auto result = manapi::json::parse(R"({"hello": "world", "world": "hello"})").unwrap();
20+
```
21+
- Using C++ structures:
22+
```cpp
23+
manapi::json result = {
24+
{ "hello", "world" },
25+
{ "world", "hello" }
26+
};
27+
// or
28+
auto result = manapi::json::object();
29+
result.insert({ "hello", "world" });
30+
result.insert({ "world", "hello" });
31+
```
32+
33+
## Types
34+
ManapiHttp's JSON implementation supports all standard types, which can be accessed using several non-const methods.
35+
36+
```cpp
37+
// Default value is null
38+
manapi::json data;
39+
40+
// Returns reference to std::string
41+
data.as_string();
42+
43+
// Returns reference to ssize_t
44+
data.as_integer();
45+
46+
// Returns reference to long double
47+
data.as_decimal();
48+
49+
// Returns reference to bool
50+
data.as_bool();
51+
52+
// Returns nullptr
53+
data.as_null();
54+
55+
// Returns reference to std::vector<manapi::json>
56+
data.as_array();
57+
58+
// Returns reference to std::map<std::string, manapi::json, std::less<>>
59+
data.as_object();
60+
61+
// Returns reference to manapi::bigint if supported
62+
data.as_bigint();
63+
```
64+
65+
<Callout title="Information">Any of these methods will throw an exception if the type is not supported.</Callout>
66+
67+
If you need to convert between types, you can use the following casting methods:
68+
69+
```cpp
70+
// Default value is null
71+
manapi::json data;
72+
73+
// Returns std::string
74+
data.as_string_cast();
75+
76+
// Returns ssize_t
77+
data.as_integer_cast();
78+
79+
// Returns long double
80+
data.as_decimal_cast();
81+
82+
// Returns bool
83+
data.as_bool_cast();
84+
85+
// Returns nullptr
86+
data.as_null_cast();
87+
88+
// Returns std::vector<manapi::json>
89+
data.as_array_cast();
90+
91+
// Returns std::map<std::string, manapi::json, std::less<>>
92+
data.as_object_cast();
93+
94+
// Returns manapi::bigint if supported
95+
data.as_bigint_cast();
96+
```
97+
98+
<Callout title="Warning" type="warn">These methods will throw an exception if the cast is not supported.</Callout>
99+
100+
### Integer Type
101+
102+
#### Constructor
103+
```cpp
104+
manapi::json data = 100;
105+
```
106+
107+
#### Arithmetic Operations
108+
```cpp
109+
// 100 + 5 = 105
110+
data += 5;
111+
112+
// 105 - 10 = 95
113+
data -= 10;
114+
115+
// 95 * 4 = 380
116+
data *= 4;
117+
118+
// 380 / 2 = 190
119+
data /= 2;
120+
121+
// true
122+
data = (data == 190);
123+
124+
// Get the integer value
125+
ssize_t &res = data.as_integer();
126+
```
127+
128+
### String Type
129+
130+
#### Constructor
131+
```cpp
132+
manapi::json data = "hello";
133+
```
134+
135+
#### String Operations
136+
```cpp
137+
// Returns string length (5)
138+
std::size_t size = data.size();
139+
140+
// Concatenate strings
141+
data += " world";
142+
143+
// Get the string value
144+
std::string &str = data.as_string();
145+
```
146+
147+
### Bigint Type
148+
149+
#### Constructor
150+
```cpp
151+
manapi::json data = manapi::bigint("100");
152+
```
153+
154+
#### Bigint Operations
155+
```cpp
156+
// 100 + 5 = 105
157+
data += 5;
158+
159+
// 105 - 10 = 95
160+
data -= 10;
161+
162+
// 95 * 4 = 380
163+
data *= 4;
164+
165+
// 380 / 8 = 47.5
166+
data /= 8;
167+
168+
// true
169+
data = (data == 47.5);
170+
171+
// 47.5 + 1e50
172+
data += manapi::bigint("1e50");
173+
174+
// Get the bigint value
175+
manapi::bigint &res = data.as_bigint();
176+
```
177+
178+
### Decimal Type
179+
180+
#### Constructor
181+
```cpp
182+
manapi::json data = 100.0;
183+
```
184+
185+
#### Decimal Operations
186+
```cpp
187+
// 100 + 5 = 105
188+
data += 5;
189+
190+
// 105 - 10 = 95
191+
data -= 10;
192+
193+
// 95 * 4 = 380
194+
data *= 4;
195+
196+
// 380 / 8 = 47.5
197+
data /= 8;
198+
199+
// true (with floating-point tolerance)
200+
data = (data - 47.5 < 0.1);
201+
202+
// Get the decimal value
203+
long double &res = data.as_decimal();
204+
```
205+
206+
### Array Type
207+
208+
#### Constructor
209+
```cpp
210+
// For 2 or fewer elements in std::initializer_list<T>
211+
manapi::json data = manapi::json::array({"hello", "world"});
212+
// For more than 2 elements
213+
manapi::json data {"hello", "world", "yes"};
214+
```
215+
216+
#### Array Operations
217+
```cpp
218+
manapi::json data = manapi::json::array({"hello", "world"});
219+
220+
data.push_back("hello");
221+
222+
data.pop_back();
223+
224+
// Returns 2
225+
data.size();
226+
227+
// Get the vector
228+
std::vector<manapi::json> &res = data.as_array();
229+
```
230+
231+
### Object Type
232+
233+
#### Constructor
234+
```cpp
235+
// For objects with only one key-value pair
236+
manapi::json data = manapi::json::object({{"data", "hello"}});
237+
// For multiple key-value pairs
238+
manapi::json data = {{"data", "hello"}, {"hello", "data"}};
239+
```
240+
241+
#### Object Operations
242+
```cpp
243+
manapi::json data = {{"data", "hello"}, {"hello", "data"}};
244+
245+
// Insert a new key-value pair
246+
data.insert({{"world", "hello"}});
247+
248+
// Remove a key
249+
data.erase("world");
250+
251+
// Returns 2
252+
data.size();
253+
254+
// Get the map
255+
std::map<std::string, manapi::json, std::less<>> &res = data.as_object();
256+
```
257+
258+
## Serializing JSON
259+
260+
### Compact Output (without whitespace)
261+
```cpp
262+
manapi::json data = manapi::json::object({
263+
{"hello", "world"}
264+
});
265+
266+
// Outputs: {"hello":"world"}
267+
std::cout << data.dump() << "\n";
268+
```
269+
270+
### Formatted Output (with indentation)
271+
```cpp
272+
manapi::json data = manapi::json::object({
273+
{"hello", "world"}
274+
});
275+
276+
std::cout << data.dump(4) << "\n";
277+
```
278+
279+
Output:
280+
```json
281+
{
282+
"hello": "world"
283+
}
284+
```
285+
286+
## Incremental Parsing
287+
288+
The ```manapi::json_builder``` class allows incremental JSON parsing in chunks.
289+
290+
```cpp
291+
...
292+
#include <manapihttp/json/ManapiJsonBuilder.hpp>
293+
...
294+
295+
manapi::json_builder builder();
296+
297+
builder << R"({"hello)";
298+
builder << R"(": "hello)";
299+
builder << R"(helllooo"})";
300+
301+
manapi::json res = builder.get().unwrap();
302+
303+
// Alternative approach:
304+
305+
manapi::json_builder builder();
306+
307+
builder.parse(R"({"hello)").unwrap();
308+
builder.parse(R"(": "hello)").unwrap();
309+
builder.parse(R"(helllooo"})").unwrap();
310+
311+
manapi::json res = builder.get().unwrap();
312+
```
313+
314+
<Callout title="Why is this useful?">
315+
```manapi::json_builder``` combined with ```manapi::json_mask``` is used by the HTTP layer to process chunked data.
316+
</Callout>
317+
318+
This approach provides early error detection - if the body is large and contains an error in the middle, it will fail immediately without processing the entire input.
319+
320+
```cpp
321+
manapi::json_mask mask = {
322+
{"hello", R"({string(<16)})"}
323+
};
324+
325+
// ✅ Valid usage:
326+
327+
manapi::json_builder builder(mask);
328+
builder << R"({"hello)";
329+
builder << R"(": "hello)";
330+
builder << R"(helllooo"})";
331+
332+
auto obj = builder.get().unwrap();
333+
334+
...
335+
336+
// Invalid usage (string too long):
337+
338+
manapi::json_builder builder(mask);
339+
builder << R"({"hello)";
340+
builder << R"(": "hello)";
341+
// Generates an error - string exceeds maximum length
342+
builder << R"(hellloooooooooooooooooooooooooo)";
343+
builder << R"(o"})";
344+
345+
auto obj = builder.get().unwrap();
346+
```

docs/content/docs/meta.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"pages": [
44
"---Introduction---",
55
"intro/install",
6-
"intro/quick-start"
6+
"intro/quick-start",
7+
"---Data Formats---",
8+
"data-formats/json"
79
]
810
}

0 commit comments

Comments
 (0)