Skip to content

Commit 52f1a11

Browse files
Refactor JSON type.
This allows coercing any `std::vector<T>` into `JSONArray` if `T` is convertible to `JSONValue`.
1 parent 891a02b commit 52f1a11

File tree

1 file changed

+23
-34
lines changed

1 file changed

+23
-34
lines changed

antithesis_sdk.h

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,20 @@ namespace antithesis {
3333
}
3434
};
3535

36-
struct JSON;
37-
typedef std::variant<std::string, bool, char, int, uint64_t, float, double, const char*, JSON> BasicValueType;
38-
typedef std::vector<BasicValueType> JSON_ARRAY;
39-
typedef std::variant<BasicValueType, JSON_ARRAY> ValueType;
36+
struct JSON; struct JSONArray;
37+
typedef std::variant<std::nullptr_t, std::string, bool, char, int, uint64_t, float, double, const char*, JSON, JSONArray> JSONValue;
4038

41-
struct JSON : std::map<std::string, ValueType> {
42-
JSON( std::initializer_list<std::pair<const std::string, ValueType>> args) : std::map<std::string, ValueType>(args) {}
39+
struct JSONArray : std::vector<JSONValue> {
40+
using std::vector<JSONValue>::vector;
4341

44-
JSON( std::initializer_list<std::pair<const std::string, ValueType>> args, std::vector<std::pair<const std::string, ValueType>> more_args ) : std::map<std::string, ValueType>(args) {
42+
template<typename T> requires std::convertible_to<T, JSONValue>
43+
JSONArray(std::vector<T> vals) : std::vector<JSONValue>(vals.begin(), vals.end()) {}
44+
};
45+
46+
struct JSON : std::map<std::string, JSONValue> {
47+
JSON( std::initializer_list<std::pair<const std::string, JSONValue>> args) : std::map<std::string, JSONValue>(args) {}
48+
49+
JSON( std::initializer_list<std::pair<const std::string, JSONValue>> args, std::vector<std::pair<const std::string, JSONValue>> more_args ) : std::map<std::string, JSONValue>(args) {
4550
for (auto& pair : more_args) {
4651
(*this)[pair.first] = pair.second;
4752
}
@@ -264,7 +269,7 @@ namespace antithesis {
264269
template<class>
265270
inline constexpr bool always_false_v = false;
266271

267-
static std::ostream& operator<<(std::ostream& out, const BasicValueType& basic_value) {
272+
static std::ostream& operator<<(std::ostream& out, const JSONValue& json) {
268273
std::visit([&](auto&& arg)
269274
{
270275
using T = std::decay_t<decltype(arg)>;
@@ -285,41 +290,25 @@ namespace antithesis {
285290
out << arg;
286291
} else if constexpr (std::is_same_v<T, const char*>) {
287292
out << std::quoted(arg);
293+
} else if constexpr (std::is_same_v<T, std::nullptr_t>) {
294+
out << "null";
288295
} else if constexpr (std::is_same_v<T, JSON>) {
289-
if (arg.empty()) {
290-
out << "null";
291-
} else {
292-
out << arg;
293-
}
294-
} else {
295-
static_assert(always_false_v<T>, "non-exhaustive BasicValueType visitor!");
296-
}
297-
}, basic_value);
298-
299-
return out;
300-
}
301-
302-
static std::ostream& operator<<(std::ostream& out, const ValueType& value) {
303-
std::visit([&](auto&& arg)
304-
{
305-
using T = std::decay_t<decltype(arg)>;
306-
if constexpr (std::is_same_v<T, BasicValueType>) {
307296
out << arg;
308-
} else if constexpr (std::is_same_v<T, std::vector<BasicValueType>>) {
297+
} else if constexpr (std::is_same_v<T, JSONArray>) {
309298
out << '[';
310299
bool first = true;
311300
for (auto &item : arg) {
312-
if (!first) {
313-
out << ',';
314-
}
315-
first = false;
316-
out << item;
301+
if (!first) {
302+
out << ", ";
303+
}
304+
first = false;
305+
out << item;
317306
}
318307
out << ']';
319308
} else {
320-
static_assert(always_false_v<T>, "non-exhaustive ValueType visitor!");
309+
static_assert(always_false_v<T>, "non-exhaustive JSONValue visitor!");
321310
}
322-
}, value);
311+
}, json);
323312

324313
return out;
325314
}

0 commit comments

Comments
 (0)