#pragma once #include #include "commons/commons_base.h" struct json_value; auto API JsonValue_GetNext(json_value& self) -> json_value*; void JsonValue_Log(json_value* val, uint32_t indent = 0); struct json_value_iterator { json_value* p; auto operator*() const -> json_value& { return *p; } auto operator->() const -> json_value& { return *p; } auto operator==(const json_value_iterator& other) const -> bool { return p == other.p; } auto operator++() -> json_value_iterator& { p = JsonValue_GetNext(*p); return *this; } }; enum class json_tag { Invalid = 0, Null, Bool, Integer, Double, String, ArrayBegin, ArrayEnd, ObjectBegin, ObjectEnd, }; struct json_value { json_tag tag; union { bool valBool; int64_t valInt; double valDouble; byteview valStr; struct { json_value* end; uint32_t count; } valHeader; } val; auto begin() -> json_value_iterator { ASSERT(tag == json_tag::ArrayBegin || tag == json_tag::ObjectBegin); return json_value_iterator { this + 1 }; } auto end() -> json_value_iterator { ASSERT(tag == json_tag::ArrayBegin || tag == json_tag::ObjectBegin); return json_value_iterator { val.valHeader.end }; } }; INLINE auto JsonValue_GetCount(const json_value& self) { ASSERT(self.tag == json_tag::ArrayBegin || self.tag == json_tag::ObjectBegin); return self.val.valHeader.count; } INLINE auto JsonValue_GetFront(json_value& self) -> json_value* { ASSERT(self.tag == json_tag::ArrayBegin || self.tag == json_tag::ObjectBegin); return &self + 1; } INLINE void JsonValue_SetValue(json_value& self, json_tag tag) { self.tag = tag; } INLINE void JsonValue_SetValue(json_value& self, bool val) { self.tag = json_tag::Bool; self.val = { .valBool = val }; } INLINE void JsonValue_SetValue(json_value& self, int64_t val) { self.tag = json_tag::Integer; self.val = { .valInt = val }; } INLINE void JsonValue_SetValue(json_value& self, double val) { self.tag = json_tag::Double; self.val = { .valDouble = val }; } INLINE void JsonValue_SetValue(json_value& self, byteview str) { self.tag = json_tag::String; self.val = { .valStr = str }; } INLINE void JsonValue_SetValue(json_value& self, json_tag tag, uint32_t count, json_value* end) { self.tag = tag; self.val.valHeader = { .end = end, .count = count, }; } // NOLINTBEGIN(bugprone-macro-parentheses) #define X(name, out) \ auto API JsonValue_Try##name(json_value& self, span, out&) -> bool; \ INLINE auto JsonValue_##name(json_value& self, span path) -> out \ { \ out ret; \ ASSERT(JsonValue_Try##name(self, path, ret)); \ return ret; \ } \ INLINE auto JsonValue_Try##name(json_value& self, byteview path, out& ret) -> bool \ { \ return JsonValue_Try##name(self, span { &path, 1 }, ret); \ } \ INLINE auto JsonValue_##name(json_value& self, byteview path) -> out \ { \ return JsonValue_##name(self, span { &path, 1 }); \ } \ INLINE auto JsonValue_Try##name(json_value& self, out& ret) -> bool \ { \ return JsonValue_Try##name(self, span { }, ret); \ } \ INLINE auto JsonValue_##name(json_value& self) -> out \ { \ return JsonValue_##name(self, span { }); \ } // NOLINTEND(bugprone-macro-parentheses) X(Any, json_value*); X(Object, json_value*); X(Array, json_value*); X(String, byteview); X(DWord, uint32_t); X(QWord, uint64_t); X(Double, double); X(Bool, bool); #undef X