AUI Framework  master
Cross-platform module-based framework for developing C++20 desktop applications
AJson.h
1/*
2 * AUI Framework - Declarative UI toolkit for modern C++20
3 * Copyright (C) 2020-2024 Alex2772 and Contributors
4 *
5 * SPDX-License-Identifier: MPL-2.0
6 *
7 * This Source Code Form is subject to the terms of the Mozilla Public
8 * License, v. 2.0. If a copy of the MPL was not distributed with this
9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 */
11
12#pragma once
13
14#include <AUI/IO/IOutputStream.h>
15#include "AUI/Common/AException.h"
16#include "AUI/Common/AOptional.h"
17#include "AUI/Common/SharedPtr.h"
18#include "AUI/IO/IInputStream.h"
19#include "AJson.h"
20#include "AUI/Common/AByteBufferView.h"
21
22#include <AUI/Common/AUuid.h>
23#include <AUI/Common/AMap.h>
24#include <AUI/Json/AJson.h>
25#include <AUI/Json/Exception.h>
26#include <AUI/Traits/callables.h>
27#include <variant>
28
29class AJson;
30namespace aui::impl {
31 struct JsonObject: AVector<std::pair<AString, AJson>> {
32 public:
34
38 [[nodiscard]]
39 API_AUI_JSON std::pair<AString, AJson>* contains(const AString& key) noexcept;
40
44 [[nodiscard]]
45 const std::pair<AString, AJson>* contains(const AString& key) const noexcept {
46 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
47 return const_cast<JsonObject&>(*this).contains(key);
48 }
49
50 [[nodiscard]] API_AUI_JSON AJson& operator[](const AString& key);
51
52 [[nodiscard]] const AJson& operator[](const AString& key) const {
53 return at(key);
54 }
55
60 [[nodiscard]] API_AUI_JSON AJson& at(const AString& key);
61
66 [[nodiscard]] const AJson& at(const AString& key) const {
67 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
68 return const_cast<JsonObject&>(*this).at(key);
69 }
70 };
71 using JsonArray = AVector<AJson>;
72 using JsonVariant = std::variant<std::nullopt_t, std::nullptr_t, int, int64_t, double, bool, AString, aui::impl::JsonArray, aui::impl::JsonObject>;
73}
74
79class AJson: public aui::impl::JsonVariant {
80private:
81 using super = aui::impl::JsonVariant;
82
83 template<typename T>
84 [[nodiscard]]
85 bool is() const noexcept {
86 return std::holds_alternative<T>(*this);
87 }
88 template<typename T>
89 [[nodiscard]]
90 T& as() {
91 if (isEmpty()) {
92 *this = T();
93 }
94
95 if (auto p = std::get_if<T>(this)) {
96 return *p;
97 }
99 }
100
101 template<typename T>
102 [[nodiscard]]
103 const T& as() const {
104 if (auto p = std::get_if<T>(this)) {
105 return *p;
106 }
107 if constexpr(std::is_same_v<T, aui::impl::JsonObject>) {
108 throw AJsonTypeMismatchException("not an object");
109 } else if constexpr(std::is_same_v<T, aui::impl::JsonArray>) {
110 throw AJsonTypeMismatchException("not an array");
111 } else {
113 }
114 }
115public:
116 using aui::impl::JsonVariant::variant;
117
120
121 AJson(std::initializer_list<std::pair<AString, AJson>> elems): aui::impl::JsonVariant(aui::impl::JsonObject(std::move(elems))) {
122
123 }
124
125 AJson(const char* name): aui::impl::JsonVariant(AString(name)) {}
126 AJson(const AJson& json) = default;
127 AJson(AJson&&) noexcept = default;
128 AJson& operator=(const AJson&) = default;
129 AJson& operator=(AJson&&) noexcept = default;
130
131 AJson() noexcept: aui::impl::JsonVariant(std::nullopt) {}
132
133 [[nodiscard]]
134 bool isInt() const noexcept {
135 return is<int>();
136 }
137
138 [[nodiscard]]
139 bool isLongInt() const noexcept {
140 return isInt() || is<int64_t>();
141 }
142
143 [[nodiscard]]
144 bool isEmpty() const noexcept {
145 return is<std::nullopt_t>();
146 }
147
148 [[nodiscard]]
149 bool isNumber() const noexcept {
150 return isInt() || is<double>();
151 }
152
153 [[nodiscard]]
154 bool isBool() const noexcept {
155 return is<bool>();
156 }
157
158 [[nodiscard]]
159 bool isNull() const noexcept {
160 return is<std::nullptr_t>();
161 }
162
163 [[nodiscard]]
164 bool isString() const noexcept {
165 return is<AString>();
166 }
167
168 [[nodiscard]]
169 bool isArray() const noexcept {
170 return is<aui::impl::JsonArray>();
171 }
172
173 [[nodiscard]]
174 bool isObject() const noexcept {
175 return is<aui::impl::JsonObject>();
176 }
177
178 [[nodiscard]]
179 int asInt() const {
180 return as<int>();
181 }
182
183 [[nodiscard]]
184 int64_t asLongInt() const {
185 return std::visit(aui::lambda_overloaded{
186 [](auto&& e) -> std::int64_t {
187 throw AJsonTypeMismatchException("not a long int");
188 },
189 [](std::int64_t v) -> std::int64_t {
190 return v;
191 },
192 [](int v) -> std::int64_t {
193 return v;
194 },
195 }, (super)const_cast<AJson&>(*this));
196 }
197
198 [[nodiscard]]
199 double asNumber() const {
200 return std::visit(aui::lambda_overloaded{
201 [](auto&& e) -> double {
202 throw AJsonTypeMismatchException("not a number");
203 },
204 [](double v) -> double {
205 return v;
206 },
207 [](int v) -> double {
208 return v;
209 },
210 [](int64_t v) -> double {
211 return v;
212 },
213 }, (super)const_cast<AJson&>(*this));
214 }
215
216 [[nodiscard]]
217 bool asBool() const {
218 return as<bool>();
219 }
220
221 [[nodiscard]]
222 const AString& asString() const {
223 return as<AString>();
224 }
225
226 [[nodiscard]]
227 const aui::impl::JsonArray& asArray() const {
228 return as<aui::impl::JsonArray>();
229 }
230
231 [[nodiscard]]
232 const aui::impl::JsonObject& asObject() const {
233 return as<aui::impl::JsonObject>();
234 }
235
236
237 [[nodiscard]]
238 aui::impl::JsonArray& asArray() {
239 return as<aui::impl::JsonArray>();
240 }
241
242 [[nodiscard]]
243 aui::impl::JsonObject& asObject() {
244 return as<Object>();
245 }
246
247 [[nodiscard]]
248 bool contains(const AString& mapKey) const {
249 return as<Object>().contains(mapKey);
250 }
251
252 [[nodiscard]]
253 AOptional<AJson> containsOpt(const AString& mapKey) const {
254 if (auto c = as<Object>().contains(mapKey)) {
255 return c->second;
256 }
257 return std::nullopt;
258 }
259
260 AJson& operator[](const AString& mapKey) {
261 return asObject()[mapKey];
262 }
263
264 const AJson& operator[](const AString& mapKey) const {
265 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
266 return const_cast<AJson&>(*this)[mapKey];
267 }
268
269
270 AJson& operator[](int arrayIndex) {
271 return as<Array>().at(arrayIndex);
272 }
273
274 const AJson& operator[](int arrayIndex) const {
275 return const_cast<AJson&>(*this)[arrayIndex];
276 }
277
278 void push_back(AJson elem) {
279 asArray().push_back(std::move(elem));
280 }
281
282
309 API_AUI_JSON AJson mergedWith(const AJson& other);
310
311 [[nodiscard]] static API_AUI_JSON AString toString(const AJson& json);
312 [[nodiscard]] static API_AUI_JSON AJson fromString(const AString& json);
313 [[nodiscard]] static AJson fromStream(aui::no_escape<IInputStream> stream) {
314 return aui::deserialize<AJson>(stream);
315 }
316 [[nodiscard]] static API_AUI_JSON AJson fromBuffer(AByteBufferView buffer);
317};
318
319
320#include <AUI/Json/Conversion.h>
321#include <AUI/Json/Serialization.h>
Acts like std::string_view but for AByteBuffer.
Definition: AByteBufferView.h:24
Definition: AClass.h:18
Definition: Exception.h:33
Json atom.
Definition: AJson.h:79
API_AUI_JSON AJson mergedWith(const AJson &other)
Merges other json object into this object.
Definition: AJson.cpp:33
Utility wrapper implementing the stack-allocated (fast) optional idiom.
Definition: AOptional.h:32
Represents a Unicode character string.
Definition: AString.h:37
A std::vector with AUI extensions.
Definition: AVector.h:38
Definition: AJson.h:31
const AJson & at(const AString &key) const
If container contains key, returns reference to the element.
Definition: AJson.h:66
API_AUI_JSON std::pair< AString, AJson > * contains(const AString &key) noexcept
If container contains key, returns pointer to the element. nullptr otherwise.
Definition: AJson.cpp:44
API_AUI_JSON AJson & at(const AString &key)
If container contains key, returns reference to the element.
Definition: AJson.cpp:59
const std::pair< AString, AJson > * contains(const AString &key) const noexcept
If container contains key, returns pointer to the element. nullptr otherwise.
Definition: AJson.h:45
Definition: callables.h:34
Does not allow escaping, allowing to accept lvalue ref, rvalue ref, shared_ptr and etc without overhe...
Definition: values.h:127