Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Concepts.h>
10#include <AK/Error.h>
11#include <AK/JsonArraySerializer.h>
12#include <AK/JsonValue.h>
13#include <AK/Vector.h>
14
15namespace AK {
16
17class JsonArray {
18 template<typename Callback>
19 using CallbackErrorType = decltype(declval<Callback>()(declval<JsonValue const&>()).release_error());
20
21public:
22 JsonArray() = default;
23 ~JsonArray() = default;
24
25 JsonArray(JsonArray const& other)
26 : m_values(other.m_values)
27 {
28 }
29
30 JsonArray(JsonArray&& other)
31 : m_values(move(other.m_values))
32 {
33 }
34
35 template<IterableContainer ContainerT>
36 JsonArray(ContainerT const& source)
37 {
38 for (auto& value : source)
39 m_values.append(move(value));
40 }
41
42 JsonArray& operator=(JsonArray const& other)
43 {
44 if (this != &other)
45 m_values = other.m_values;
46 return *this;
47 }
48
49 JsonArray& operator=(JsonArray&& other)
50 {
51 if (this != &other)
52 m_values = move(other.m_values);
53 return *this;
54 }
55
56 [[nodiscard]] size_t size() const { return m_values.size(); }
57 [[nodiscard]] bool is_empty() const { return m_values.is_empty(); }
58
59 [[nodiscard]] JsonValue const& at(size_t index) const { return m_values.at(index); }
60 [[nodiscard]] JsonValue const& operator[](size_t index) const { return at(index); }
61
62 [[nodiscard]] JsonValue take(size_t index) { return m_values.take(index); }
63
64 void clear() { m_values.clear(); }
65 void append(JsonValue value) { m_values.append(move(value)); }
66 void set(size_t index, JsonValue value) { m_values[index] = move(value); }
67
68 template<typename Builder>
69 typename Builder::OutputType serialized() const;
70
71 template<typename Builder>
72 void serialize(Builder&) const;
73
74 [[nodiscard]] DeprecatedString to_deprecated_string() const { return serialized<StringBuilder>(); }
75
76 template<typename Callback>
77 void for_each(Callback callback) const
78 {
79 for (auto const& value : m_values)
80 callback(value);
81 }
82
83 template<FallibleFunction<JsonValue const&> Callback>
84 ErrorOr<void, CallbackErrorType<Callback>> try_for_each(Callback&& callback) const
85 {
86 for (auto const& value : m_values)
87 TRY(callback(value));
88 return {};
89 }
90
91 [[nodiscard]] Vector<JsonValue> const& values() const { return m_values; }
92
93 void ensure_capacity(size_t capacity) { m_values.ensure_capacity(capacity); }
94
95private:
96 Vector<JsonValue> m_values;
97};
98
99template<typename Builder>
100inline void JsonArray::serialize(Builder& builder) const
101{
102 auto serializer = MUST(JsonArraySerializer<>::try_create(builder));
103 for_each([&](auto& value) { MUST(serializer.add(value)); });
104 MUST(serializer.finish());
105}
106
107template<typename Builder>
108inline typename Builder::OutputType JsonArray::serialized() const
109{
110 Builder builder;
111 serialize(builder);
112 return builder.to_deprecated_string();
113}
114
115}
116
117#if USING_AK_GLOBALLY
118using AK::JsonArray;
119#endif