userver: userver/formats/bson/value_builder.hpp Source File
Loading...
Searching...
No Matches
value_builder.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/formats/bson/value_builder.hpp
4/// @brief @copybrief formats::bson::ValueBuilder
5
6#include <chrono>
7#include <cstddef>
8#include <cstdint>
9#include <string>
10#include <string_view>
11
12#include <userver/formats/bson/document.hpp>
13#include <userver/formats/bson/iterator.hpp>
14#include <userver/formats/bson/types.hpp>
15#include <userver/formats/bson/value.hpp>
16#include <userver/formats/common/meta.hpp>
17#include <userver/formats/common/transfer_tag.hpp>
18#include <userver/formats/common/type.hpp>
19#include <userver/utils/strong_typedef.hpp>
20
21USERVER_NAMESPACE_BEGIN
22
23namespace formats::bson {
24
25// clang-format off
26
27/// @brief Builder for BSON.
28///
29/// Class provides methods for building BSON. For read only access to the
30/// existing BSON values use formats::bson::Value.
31///
32/// ## Example usage:
33///
34/// @snippet formats/bson/value_builder_test.cpp Sample formats::bson::ValueBuilder usage
35///
36/// ## Customization example:
37///
38/// @snippet formats/bson/value_builder_test.cpp Sample Customization formats::bson::ValueBuilder usage
39///
40/// @see @ref scripts/docs/en/userver/formats.md
41
42// clang-format on
43
45 public:
47 using Type = formats::common::Type;
48
49 /// Constructs a `null` value (may be used as either document or array)
51
52 /// Constructs a value with the predefined type
53 explicit ValueBuilder(Type);
54
55 /// @cond
56 /// Constructor from implementation, internal use only
57 explicit ValueBuilder(impl::ValueImplPtr);
58 /// @endcond
59
60 ValueBuilder(const ValueBuilder& other);
61 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
62 ValueBuilder(ValueBuilder&& other);
63 ValueBuilder& operator=(const ValueBuilder& other);
64 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
65 ValueBuilder& operator=(ValueBuilder&& other);
66
67 /// @{
68 /// Efficiently constructs a copy of an existing value
70 ValueBuilder(const Document&);
71 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
72 ValueBuilder(Value&&);
73 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
74 ValueBuilder(Document&&);
75 /// @}
76
77 /// @name Concrete type constructors
78 /// @{
79 /* implicit */ ValueBuilder(std::nullptr_t);
80 /* implicit */ ValueBuilder(bool);
81 /* implicit */ ValueBuilder(int);
82 /* implicit */ ValueBuilder(unsigned int);
83 /* implicit */ ValueBuilder(long);
84 /* implicit */ ValueBuilder(unsigned long);
85 /* implicit */ ValueBuilder(long long);
86 /* implicit */ ValueBuilder(unsigned long long);
87 /* implicit */ ValueBuilder(double);
88 /* implicit */ ValueBuilder(const char*);
89 /* implicit */ ValueBuilder(std::string);
90 /* implicit */ ValueBuilder(std::string_view);
91 /* implicit */ ValueBuilder(const std::chrono::system_clock::time_point&);
92 /* implicit */ ValueBuilder(const Oid&);
93 /* implicit */ ValueBuilder(Binary);
94 /* implicit */ ValueBuilder(const Decimal128&);
95 /* implicit */ ValueBuilder(MinKey);
96 /* implicit */ ValueBuilder(MaxKey);
97 /* implicit */ ValueBuilder(const Timestamp&);
98 /// @}
99
100 /// Universal constructor using Serialize
101 template <typename T>
102 ValueBuilder(const T& t) : ValueBuilder(DoSerialize(t)) {}
103
104 /// @brief Transfers the `ValueBuilder` object
105 /// @see formats::common::TransferTag for the transfer semantics
106 ValueBuilder(common::TransferTag, ValueBuilder&&) noexcept;
107
108 /// @brief Retrieves or creates document field by name
109 /// @throws TypeMismatchException if value is not a document or `null`
110 ValueBuilder operator[](const std::string& name);
111
112 /// @brief Emplaces new member w/o a check whether the key already exists.
113 /// @warning May create invalid BSON with duplicate key.
114 /// @throw `TypeMismatchException` if not object or null value.
115 void EmplaceNocheck(std::string_view key, ValueBuilder value);
116
117 /// @brief Access member by key for modification.
118 /// @throw `TypeMismatchException` if not object or null value.
119 template <
120 typename Tag, utils::StrongTypedefOps Ops,
121 typename Enable = std::enable_if_t<utils::IsStrongTypedefLoggable(Ops)>>
123 const utils::StrongTypedef<Tag, std::string, Ops>& name);
124
125 /// @brief Retrieves array element by index
126 /// @throws TypeMismatchException if value is not an array or `null`
127 /// @throws OutOfBoundsException if index is invalid for the array
128 ValueBuilder operator[](uint32_t index);
129
130 /// @brief Remove key from object. If key is missing nothing happens.
131 /// @throw `TypeMismatchException` if value is not an object.
132 void Remove(const std::string& key);
133
134 /// @brief Returns an iterator to the first array element/document field
135 /// @throws TypeMismatchException if value is not a document, array or `null`
137
138 /// @brief Returns an iterator following the last array element/document field
139 /// @throws TypeMismatchException if value is not a document, array or `null`
141
142 /// @brief Returns whether the document/array is empty
143 /// @throws TypeMismatchException if value is not a document, array or `null`
144 /// @note Returns `true` for `null`.
145 bool IsEmpty() const;
146
147 /// @brief Returns true if *this holds a Null (Type::kNull).
148 bool IsNull() const noexcept;
149
150 /// @brief Returns true if *this is convertible to bool.
151 bool IsBool() const noexcept;
152
153 /// @brief Returns true if *this is convertible to int.
154 bool IsInt() const noexcept;
155
156 /// @brief Returns true if *this is convertible to int64_t.
157 bool IsInt64() const noexcept;
158
159 /// @brief Returns true if *this is convertible to uint64_t.
160 bool IsUInt64() const noexcept;
161
162 /// @brief Returns true if *this is convertible to double.
163 bool IsDouble() const noexcept;
164
165 /// @brief Returns true if *this is convertible to std::string.
166 bool IsString() const noexcept;
167
168 /// @brief Returns true if *this is an array (Type::kArray).
169 bool IsArray() const noexcept;
170
171 /// @brief Returns true if *this holds a document (BSON_TYPE_DOCUMENT).
172 bool IsObject() const noexcept;
173
174 /// @brief Returns the number of elements in a document/array
175 /// @throws TypeMismatchException if value is not a document, array or `null`
176 /// @note Returns 0 for `null`.
177 uint32_t GetSize() const;
178
179 /// @brief Checks whether the document has a field
180 /// @param name field name
181 /// @throws TypeMismatchExcepiton if value is not a document or `null`
182 bool HasMember(const std::string& name) const;
183
184 /// @brief Creates or resizes the array
185 /// @param size new size
186 /// @throws TypeMismatchException if value is not an array or `null`
187 void Resize(uint32_t size);
188
189 /// @brief Appends an element to the array, possibly creating one
190 /// @param elem element to append
191 /// @throws TypeMismatchException if value is not an array or `null`
192 void PushBack(ValueBuilder&& elem);
193
194 /// @brief Retrieves a compiled value from the builder.
195 /// After calling this method the builder is in unspecified state.
197
198 private:
199 void Assign(const impl::ValueImplPtr&);
200 void Assign(impl::ValueImplPtr&&);
201
202 template <typename T>
203 static Value DoSerialize(const T& t);
204
205 impl::ValueImplPtr impl_;
206};
207
208template <typename Tag, utils::StrongTypedefOps Ops, typename Enable>
210 const utils::StrongTypedef<Tag, std::string, Ops>& name) {
211 return (*this)[name.GetUnderlying()];
212}
213
214template <typename T>
215Value ValueBuilder::DoSerialize(const T& t) {
216 static_assert(
217 formats::common::impl::kHasSerialize<Value, T>,
218 "There is no `Serialize(const T&, formats::serialize::To<bson::Value>)` "
219 "in namespace of `T` or `formats::serialize`. "
220 ""
221 "Probably you forgot to include the "
222 "<userver/formats/serialize/common_containers.hpp> or you "
223 "have not provided a `Serialize` function overload.");
224
225 return Serialize(t, formats::serialize::To<Value>());
226}
227
228} // namespace formats::bson
229
230USERVER_NAMESPACE_END