Skip to content

Commit e61e23b

Browse files
Add type-checking methods to json class and update tests
1 parent 036cfd3 commit e61e23b

File tree

3 files changed

+139
-10
lines changed

3 files changed

+139
-10
lines changed

include/json.hpp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,81 @@ namespace json
401401
*/
402402
const json &operator[](size_t index) const { return std::get<std::vector<json>>(value).at(index); }
403403

404+
/**
405+
* @brief Checks if the JSON value is null.
406+
*
407+
* @return true if the JSON value is null, false otherwise.
408+
*/
409+
[[nodiscard]] bool is_null() const noexcept { return value.index() == 0; }
410+
/**
411+
* @brief Checks if the JSON value is a boolean.
412+
*
413+
* @return true if the JSON value is a boolean, false otherwise.
414+
*/
415+
[[nodiscard]] bool is_boolean() const noexcept { return value.index() == 1; }
416+
/**
417+
* @brief Checks if the JSON value is an integer.
418+
*
419+
* @return true if the JSON value is an integer, false otherwise.
420+
*/
421+
[[nodiscard]] bool is_integer() const noexcept { return value.index() == 2; }
422+
/**
423+
* @brief Checks if the JSON value is an unsigned integer.
424+
*
425+
* @return true if the JSON value is an unsigned integer, false otherwise.
426+
*/
427+
[[nodiscard]] bool is_unsigned() const noexcept { return value.index() == 3; }
428+
/**
429+
* @brief Checks if the JSON value is a floating-point number.
430+
*
431+
* @return true if the JSON value is a floating-point number, false otherwise.
432+
*/
433+
[[nodiscard]] bool is_float() const noexcept { return value.index() == 4; }
434+
/**
435+
* @brief Checks if the JSON value is a number.
436+
*
437+
* This function checks if the JSON value is of type integer, unsigned integer, or floating-point number.
438+
*
439+
* @return true if the JSON value is a number, false otherwise.
440+
*/
441+
[[nodiscard]] bool is_number() const noexcept { return value.index() == 2 || value.index() == 3 || value.index() == 4; }
442+
/**
443+
* @brief Checks if the JSON value is a string.
444+
*
445+
* @return true if the JSON value is a string, false otherwise.
446+
*/
447+
[[nodiscard]] bool is_string() const noexcept { return value.index() == 5; }
448+
/**
449+
* @brief Checks if the JSON value is an object.
450+
*
451+
* @return true if the JSON value is an object, false otherwise.
452+
*/
453+
[[nodiscard]] bool is_object() const noexcept { return value.index() == 6; }
454+
/**
455+
* @brief Checks if the JSON value is an array.
456+
*
457+
* @return true if the JSON value is an array, false otherwise.
458+
*/
459+
[[nodiscard]] bool is_array() const noexcept { return value.index() == 7; }
460+
461+
/**
462+
* @brief Checks if the JSON value is a primitive type.
463+
*
464+
* This function checks if the JSON value is of a primitive type, which includes null, boolean, integer, unsigned integer,
465+
* floating-point number, or string.
466+
*
467+
* @return true if the JSON value is a primitive type, false otherwise.
468+
*/
469+
[[nodiscard]] bool is_primitive() const noexcept { return is_null() || is_boolean() || is_integer() || is_unsigned() || is_float() || is_string(); }
470+
/**
471+
* @brief Checks if the JSON value is a structured type.
472+
*
473+
* This function checks if the JSON value is either an object or an array.
474+
*
475+
* @return true if the JSON value is a structured type (object or array), false otherwise.
476+
*/
477+
[[nodiscard]] bool is_structured() const noexcept { return is_object() || is_array(); }
478+
404479
/**
405480
* @brief Returns the type of the JSON value.
406481
*
@@ -459,7 +534,7 @@ namespace json
459534
* @param key The key to check for.
460535
* @return True if the key is present in the JSON object, false otherwise.
461536
*/
462-
[[nodiscard]] bool contains(std::string_view key) const { return get_type() == json_type::object && std::get<std::map<std::string, json, std::less<>>>(value).count(key) > 0; }
537+
[[nodiscard]] bool contains(std::string_view key) const { return is_object() && std::get<std::map<std::string, json, std::less<>>>(value).count(key) > 0; }
463538

464539
/**
465540
* @brief Overloads the equality operator for comparing two json objects.

src/json.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ namespace json
66
{
77
json::json(std::initializer_list<json> init)
88
{
9-
if (init.size() == 2 && init.begin()->get_type() == json_type::string)
9+
if (init.size() == 2 && init.begin()->is_string())
1010
{ // we have a key-value pair..
1111
value = std::map<std::string, json, std::less<>>();
1212
std::get<std::map<std::string, json, std::less<>>>(value)[static_cast<std::string>(*init.begin())] = *(init.begin() + 1);
1313
}
1414
else if (std::all_of(init.begin(), init.end(), [](const json &j)
15-
{ return j.get_type() == json_type::object && j.size() == 1; }))
15+
{ return j.is_object() && j.size() == 1; }))
1616
{ // we have an array of key-value pairs..
1717
value = std::map<std::string, json, std::less<>>();
1818
for (const auto &j : init)
@@ -307,7 +307,7 @@ namespace json
307307
{ // we have a type..
308308
if (schema["type"] == "object")
309309
{
310-
if (value.get_type() != json_type::object)
310+
if (!value.is_object())
311311
return false;
312312
for (const auto &property : schema["properties"].as_object())
313313
{
@@ -320,7 +320,7 @@ namespace json
320320
}
321321
else if (schema["type"] == "array")
322322
{
323-
if (value.get_type() != json_type::array)
323+
if (!value.is_array())
324324
return false;
325325
if (schema.contains("minItems"))
326326
{
@@ -341,15 +341,15 @@ namespace json
341341
}
342342
else if (schema["type"] == "string")
343343
{
344-
if (value.get_type() != json_type::string)
344+
if (!value.is_string())
345345
return false;
346346
if (schema.contains("enum"))
347347
return std::find(schema["enum"].as_array().begin(), schema["enum"].as_array().end(), value) != schema["enum"].as_array().end();
348348
return true;
349349
}
350350
else if (schema["type"] == "number")
351351
{
352-
if (value.get_type() != json_type::number)
352+
if (!value.is_number())
353353
return false;
354354
if (schema.contains("minimum"))
355355
{
@@ -369,7 +369,7 @@ namespace json
369369
}
370370
else if (schema["type"] == "integer")
371371
{
372-
if (value.get_type() != json_type::number)
372+
if (!value.is_number())
373373
return false;
374374
if (schema.contains("minimum"))
375375
{
@@ -388,9 +388,9 @@ namespace json
388388
return true;
389389
}
390390
else if (schema["type"] == "boolean")
391-
return value.get_type() == json_type::boolean;
391+
return value.is_boolean();
392392
else if (schema["type"] == "null")
393-
return value.get_type() == json_type::null;
393+
return value.is_null();
394394
else if (schema["type"] == "any")
395395
return true;
396396
else

tests/test_json.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,69 +7,88 @@ void test_constructors()
77
{
88
json::json j0;
99
assert(j0.get_type() == json::json_type::object);
10+
assert(j0.is_object());
1011
assert(j0.size() == 0);
1112

1213
json::json j1(1);
1314
assert(j1.get_type() == json::json_type::number);
15+
assert(j1.is_number());
16+
assert(j1.is_integer());
17+
assert(!j1.is_float());
1418
assert(j1 == 1);
1519
assert(j1.size() == 0);
1620

1721
json::json j2(2.0);
1822
assert(j2.get_type() == json::json_type::number);
23+
assert(j2.is_number());
24+
assert(!j2.is_integer());
25+
assert(j2.is_float());
1926
assert(j2 == 2.0);
2027
assert(j2.size() == 0);
2128

2229
json::json j3("3");
2330
assert(j3.get_type() == json::json_type::string);
31+
assert(j3.is_string());
2432
assert(j3 == "3");
2533
assert(j3.size() == 0);
2634

2735
json::json j4(true);
2836
assert(j4.get_type() == json::json_type::boolean);
37+
assert(j4.is_boolean());
2938
assert(j4 == true);
3039
assert(j4.size() == 0);
3140

3241
json::json j5(nullptr);
3342
assert(j5.get_type() == json::json_type::null);
43+
assert(j5.is_null());
3444
assert(j5 == nullptr);
3545
assert(j5.size() == 0);
3646

3747
json::json j6(json::json_type::array);
3848
assert(j6.get_type() == json::json_type::array);
49+
assert(j6.is_array());
3950
assert(j6.size() == 0);
4051

4152
json::json j7(json::json_type::object);
4253
assert(j7.get_type() == json::json_type::object);
54+
assert(j7.is_object());
4355
assert(j7.size() == 0);
4456
}
4557

4658
void test_constructors2()
4759
{
4860
json::json j0(json::json_type::null);
4961
assert(j0.get_type() == json::json_type::null);
62+
assert(j0.is_null());
5063
assert(j0 == nullptr);
5164
assert(j0.size() == 0);
5265

5366
json::json j1(json::json_type::array);
5467
assert(j1.get_type() == json::json_type::array);
68+
assert(j1.is_array());
5569
assert(j1.size() == 0);
5670

5771
json::json j2(json::json_type::object);
5872
assert(j2.get_type() == json::json_type::object);
73+
assert(j2.is_object());
5974
assert(j2.size() == 0);
6075

6176
json::json j3(json::json_type::number);
6277
assert(j3.get_type() == json::json_type::number);
78+
assert(j3.is_number());
79+
assert(j3.is_integer() || j3.is_float());
6380
assert(j3 == 0);
6481
assert(j3.size() == 0);
6582

6683
json::json j4(json::json_type::string);
6784
assert(j4.get_type() == json::json_type::string);
85+
assert(j4.is_string());
6886
assert(j4 == "");
6987
assert(j4.size() == 0);
7088

7189
json::json j5(json::json_type::boolean);
7290
assert(j5.get_type() == json::json_type::boolean);
91+
assert(j5.is_boolean());
7392
assert(j5 == false);
7493
assert(j5.size() == 0);
7594

@@ -78,11 +97,14 @@ void test_constructors2()
7897
j6.push_back(2);
7998
j6.push_back(3);
8099
assert(j6.get_type() == json::json_type::array);
100+
assert(j6.is_array());
81101
assert(j6.size() == 3);
82102

83103
json::json j7(std::move(j6));
84104
assert(j6.get_type() == json::json_type::null);
105+
assert(j6.is_null());
85106
assert(j7.get_type() == json::json_type::array);
107+
assert(j7.is_array());
86108
assert(j7.size() == 3);
87109
assert(j7[0] == 1);
88110
assert(j7[1] == 2);
@@ -98,35 +120,46 @@ void test_assignments()
98120

99121
json::json j1 = 1;
100122
assert(j1.get_type() == json::json_type::number);
123+
assert(j1.is_number());
124+
assert(j1.is_integer());
125+
assert(!j1.is_float());
101126
assert(j1 == 1);
102127
assert(j1.size() == 0);
103128

104129
json::json j2 = 2.0;
105130
assert(j2.get_type() == json::json_type::number);
131+
assert(j2.is_number());
132+
assert(!j2.is_integer());
133+
assert(j2.is_float());
106134
assert(j2 == 2.0);
107135
assert(j2.size() == 0);
108136

109137
json::json j3 = "3";
110138
assert(j3.get_type() == json::json_type::string);
139+
assert(j3.is_string());
111140
assert(j3 == "3");
112141
assert(j3.size() == 0);
113142

114143
json::json j4 = true;
115144
assert(j4.get_type() == json::json_type::boolean);
145+
assert(j4.is_boolean());
116146
assert(j4 == true);
117147
assert(j4.size() == 0);
118148

119149
json::json j5 = nullptr;
120150
assert(j5.get_type() == json::json_type::null);
151+
assert(j5.is_null());
121152
assert(j5 == nullptr);
122153
assert(j5.size() == 0);
123154

124155
json::json j6 = json::json_type::array;
125156
assert(j6.get_type() == json::json_type::array);
157+
assert(j6.is_array());
126158
assert(j6.size() == 0);
127159

128160
json::json j7 = json::json_type::object;
129161
assert(j7.get_type() == json::json_type::object);
162+
assert(j7.is_object());
130163
assert(j7.size() == 0);
131164
}
132165

@@ -329,35 +362,47 @@ void test_null()
329362
json::json j0 = nullptr;
330363
assert(j0 == nullptr);
331364
assert(j0.get_type() == json::json_type::null);
365+
assert(j0.is_null());
332366
assert(j0.dump() == "null");
333367
}
334368

335369
void test_empty_array()
336370
{
337371
json::json j0 = json::json_type::array;
338372
assert(j0.get_type() == json::json_type::array);
373+
assert(j0.is_array());
339374
assert(j0.dump() == "[]");
340375
}
341376

342377
void test_empty_object()
343378
{
344379
json::json j0 = json::json_type::object;
345380
assert(j0.get_type() == json::json_type::object);
381+
assert(j0.is_object());
346382
assert(j0.dump() == "{}");
347383
}
348384

349385
void test_scientific_numbers()
350386
{
351387
json::json j0 = 1e+10;
352388
assert(j0.get_type() == json::json_type::number);
389+
assert(j0.is_number());
390+
assert(!j0.is_integer());
391+
assert(j0.is_float());
353392
assert(j0.dump() == std::to_string(1e+10));
354393

355394
json::json j1 = 1.23e+10;
356395
assert(j1.get_type() == json::json_type::number);
396+
assert(j1.is_number());
397+
assert(!j1.is_integer());
398+
assert(j1.is_float());
357399
assert(j1.dump() == std::to_string(1.23e+10));
358400

359401
json::json j2 = .23e+10;
360402
assert(j2.get_type() == json::json_type::number);
403+
assert(j2.is_number());
404+
assert(!j2.is_integer());
405+
assert(j2.is_float());
361406
assert(j2.dump() == std::to_string(.23e+10));
362407
}
363408

@@ -368,6 +413,15 @@ void test_array_of_scientific_numbers()
368413
j0.push_back(1.23e+10);
369414
j0.push_back(.23e+10);
370415
assert(j0.get_type() == json::json_type::array);
416+
assert(j0[0].is_number());
417+
assert(!j0[0].is_integer());
418+
assert(j0[0].is_float());
419+
assert(j0[1].is_number());
420+
assert(!j0[1].is_integer());
421+
assert(j0[1].is_float());
422+
assert(j0[2].is_number());
423+
assert(!j0[2].is_integer());
424+
assert(j0[2].is_float());
371425
assert(j0.dump() == "[" + std::to_string(1e+10) + "," + std::to_string(1.23e+10) + "," + std::to_string(.23e+10) + "]");
372426
}
373427

0 commit comments

Comments
 (0)