/src/serenity/AK/JsonObject.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> |
3 | | * Copyright (c) 2021, Max Wipfli <mail@maxwipfli.ch> |
4 | | * Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org> |
5 | | * |
6 | | * SPDX-License-Identifier: BSD-2-Clause |
7 | | */ |
8 | | |
9 | | #pragma once |
10 | | |
11 | | #include <AK/ByteString.h> |
12 | | #include <AK/Concepts.h> |
13 | | #include <AK/Error.h> |
14 | | #include <AK/HashMap.h> |
15 | | #include <AK/JsonArray.h> |
16 | | #include <AK/JsonObjectSerializer.h> |
17 | | #include <AK/JsonValue.h> |
18 | | |
19 | | namespace AK { |
20 | | |
21 | | class JsonObject { |
22 | | template<typename Callback> |
23 | | using CallbackErrorType = decltype(declval<Callback>()(declval<ByteString const&>(), declval<JsonValue const&>()))::ErrorType; |
24 | | |
25 | | static_assert(SameAs<CallbackErrorType<ErrorOr<void> (*)(ByteString const&, JsonValue const&)>, Error>); |
26 | | static_assert(SameAs<ErrorOr<void, CallbackErrorType<ErrorOr<void> (*)(ByteString const&, JsonValue const&)>>, ErrorOr<void>>); |
27 | | |
28 | | public: |
29 | | JsonObject(); |
30 | | ~JsonObject(); |
31 | | |
32 | | JsonObject(JsonObject const& other); |
33 | | JsonObject(JsonObject&& other); |
34 | | |
35 | | JsonObject& operator=(JsonObject const& other); |
36 | | JsonObject& operator=(JsonObject&& other); |
37 | | |
38 | | [[nodiscard]] size_t size() const; |
39 | | [[nodiscard]] bool is_empty() const; |
40 | | |
41 | | [[nodiscard]] bool has(StringView key) const; |
42 | | |
43 | | [[nodiscard]] bool has_null(StringView key) const; |
44 | | [[nodiscard]] bool has_bool(StringView key) const; |
45 | | [[nodiscard]] bool has_string(StringView key) const; |
46 | | [[nodiscard]] bool has_i8(StringView key) const; |
47 | | [[nodiscard]] bool has_u8(StringView key) const; |
48 | | [[nodiscard]] bool has_i16(StringView key) const; |
49 | | [[nodiscard]] bool has_u16(StringView key) const; |
50 | | [[nodiscard]] bool has_i32(StringView key) const; |
51 | | [[nodiscard]] bool has_u32(StringView key) const; |
52 | | [[nodiscard]] bool has_i64(StringView key) const; |
53 | | [[nodiscard]] bool has_u64(StringView key) const; |
54 | | [[nodiscard]] bool has_number(StringView key) const; |
55 | | [[nodiscard]] bool has_array(StringView key) const; |
56 | | [[nodiscard]] bool has_object(StringView key) const; |
57 | | |
58 | | Optional<JsonValue const&> get(StringView key) const; |
59 | | |
60 | | template<Integral T> |
61 | | Optional<T> get_integer(StringView key) const |
62 | 0 | { |
63 | 0 | auto maybe_value = get(key); |
64 | 0 | if (maybe_value.has_value() && maybe_value->is_integer<T>()) |
65 | 0 | return maybe_value->as_integer<T>(); |
66 | 0 | return {}; |
67 | 0 | } Unexecuted instantiation: _ZNK2AK10JsonObject11get_integerITkNS_8Concepts8IntegralEaEENS_8OptionalIT_EENS_10StringViewE Unexecuted instantiation: _ZNK2AK10JsonObject11get_integerITkNS_8Concepts8IntegralEhEENS_8OptionalIT_EENS_10StringViewE Unexecuted instantiation: _ZNK2AK10JsonObject11get_integerITkNS_8Concepts8IntegralEsEENS_8OptionalIT_EENS_10StringViewE Unexecuted instantiation: _ZNK2AK10JsonObject11get_integerITkNS_8Concepts8IntegralEtEENS_8OptionalIT_EENS_10StringViewE Unexecuted instantiation: _ZNK2AK10JsonObject11get_integerITkNS_8Concepts8IntegralEiEENS_8OptionalIT_EENS_10StringViewE Unexecuted instantiation: _ZNK2AK10JsonObject11get_integerITkNS_8Concepts8IntegralEjEENS_8OptionalIT_EENS_10StringViewE Unexecuted instantiation: _ZNK2AK10JsonObject11get_integerITkNS_8Concepts8IntegralElEENS_8OptionalIT_EENS_10StringViewE Unexecuted instantiation: _ZNK2AK10JsonObject11get_integerITkNS_8Concepts8IntegralEmEENS_8OptionalIT_EENS_10StringViewE |
68 | | |
69 | | Optional<i8> get_i8(StringView key) const; |
70 | | Optional<u8> get_u8(StringView key) const; |
71 | | Optional<i16> get_i16(StringView key) const; |
72 | | Optional<u16> get_u16(StringView key) const; |
73 | | Optional<i32> get_i32(StringView key) const; |
74 | | Optional<u32> get_u32(StringView key) const; |
75 | | Optional<i64> get_i64(StringView key) const; |
76 | | Optional<u64> get_u64(StringView key) const; |
77 | | Optional<FlatPtr> get_addr(StringView key) const; |
78 | | Optional<bool> get_bool(StringView key) const; |
79 | | |
80 | | #if !defined(KERNEL) |
81 | | Optional<ByteString> get_byte_string(StringView key) const; |
82 | | #endif |
83 | | |
84 | | Optional<JsonObject const&> get_object(StringView key) const; |
85 | | Optional<JsonArray const&> get_array(StringView key) const; |
86 | | |
87 | | #if !defined(KERNEL) |
88 | | Optional<double> get_double_with_precision_loss(StringView key) const; |
89 | | Optional<float> get_float_with_precision_loss(StringView key) const; |
90 | | #endif |
91 | | |
92 | | void set(ByteString const& key, JsonValue value); |
93 | | |
94 | | template<typename Callback> |
95 | | void for_each_member(Callback callback) const |
96 | 0 | { |
97 | 0 | for (auto const& member : m_members) |
98 | 0 | callback(member.key, member.value); |
99 | 0 | } Unexecuted instantiation: JsonValue.cpp:void AK::JsonObject::for_each_member<AK::JsonValue::equals(AK::JsonValue const&) const::$_1>(AK::JsonValue::equals(AK::JsonValue const&) const::$_1) const Unexecuted instantiation: void AK::JsonObject::for_each_member<AK::JsonObject::serialize<AK::StringBuilder>(AK::StringBuilder&) const::{lambda(auto:1&, auto:2&)#1}>(AK::JsonObject::serialize<AK::StringBuilder>(AK::StringBuilder&) const::{lambda(auto:1&, auto:2&)#1}) const Unexecuted instantiation: JSONObject.cpp:void AK::JsonObject::for_each_member<JS::JSONObject::parse_json_object(JS::VM&, AK::JsonObject const&)::$_0>(JS::JSONObject::parse_json_object(JS::VM&, AK::JsonObject const&)::$_0) const |
100 | | |
101 | | template<FallibleFunction<ByteString const&, JsonValue const&> Callback> |
102 | | ErrorOr<void, CallbackErrorType<Callback>> try_for_each_member(Callback&& callback) const |
103 | | { |
104 | | for (auto const& member : m_members) |
105 | | TRY(callback(member.key, member.value)); |
106 | | return {}; |
107 | | } |
108 | | |
109 | | bool remove(StringView key); |
110 | | |
111 | | template<typename Builder> |
112 | | typename Builder::OutputType serialized() const; |
113 | | |
114 | | template<typename Builder> |
115 | | void serialize(Builder&) const; |
116 | | |
117 | | [[nodiscard]] ByteString to_byte_string() const; |
118 | | |
119 | | private: |
120 | | OrderedHashMap<ByteString, JsonValue> m_members; |
121 | | }; |
122 | | |
123 | | template<typename Builder> |
124 | | inline void JsonObject::serialize(Builder& builder) const |
125 | 0 | { |
126 | 0 | auto serializer = MUST(JsonObjectSerializer<>::try_create(builder)); |
127 | 0 | for_each_member([&](auto& key, auto& value) { |
128 | 0 | MUST(serializer.add(key, value)); |
129 | 0 | }); |
130 | 0 | MUST(serializer.finish()); |
131 | 0 | } |
132 | | |
133 | | template<typename Builder> |
134 | | inline typename Builder::OutputType JsonObject::serialized() const |
135 | 0 | { |
136 | 0 | Builder builder; |
137 | 0 | serialize(builder); |
138 | 0 | return builder.to_byte_string(); |
139 | 0 | } |
140 | | |
141 | | template<typename Builder> |
142 | | inline void JsonValue::serialize(Builder& builder) const |
143 | 0 | { |
144 | 0 | m_value.visit( |
145 | 0 | [&](Empty const&) { builder.append("null"sv); }, |
146 | 0 | [&](bool const& value) { builder.append(value ? "true"sv : "false"sv); }, |
147 | 0 | [&](Arithmetic auto const& value) { builder.appendff("{}", value); }, Unexecuted instantiation: auto AK::JsonValue::serialize<AK::StringBuilder>(AK::StringBuilder&) const::{lambda(auto:1 const&)#1}::operator()<long>(long const&) const Unexecuted instantiation: auto AK::JsonValue::serialize<AK::StringBuilder>(AK::StringBuilder&) const::{lambda(auto:1 const&)#1}::operator()<unsigned long>(unsigned long const&) const Unexecuted instantiation: auto AK::JsonValue::serialize<AK::StringBuilder>(AK::StringBuilder&) const::{lambda(auto:1 const&)#1}::operator()<double>(double const&) const |
148 | 0 | [&](ByteString const& value) { |
149 | 0 | builder.append('\"'); |
150 | 0 | builder.append_escaped_for_json(value.bytes()); |
151 | 0 | builder.append('\"'); |
152 | 0 | }, |
153 | 0 | [&](auto const& array_or_object) { |
154 | 0 | array_or_object->serialize(builder); |
155 | 0 | }); Unexecuted instantiation: auto AK::JsonValue::serialize<AK::StringBuilder>(AK::StringBuilder&) const::{lambda(auto:1 const&)#2}::operator()<AK::NonnullOwnPtr<AK::JsonArray> >(AK::NonnullOwnPtr<AK::JsonArray> const&) const Unexecuted instantiation: auto AK::JsonValue::serialize<AK::StringBuilder>(AK::StringBuilder&) const::{lambda(auto:1 const&)#2}::operator()<AK::NonnullOwnPtr<AK::JsonObject> >(AK::NonnullOwnPtr<AK::JsonObject> const&) const |
156 | 0 | } |
157 | | |
158 | | template<typename Builder> |
159 | | inline typename Builder::OutputType JsonValue::serialized() const |
160 | 0 | { |
161 | 0 | Builder builder; |
162 | 0 | serialize(builder); |
163 | 0 | return builder.to_byte_string(); |
164 | 0 | } |
165 | | |
166 | | } |
167 | | |
168 | | #if USING_AK_GLOBALLY |
169 | | using AK::JsonObject; |
170 | | #endif |