Coverage Report

Created: 2025-08-28 06:26

/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