userver: userver/formats/bson/serialize.hpp Source File
Loading...
Searching...
No Matches
serialize.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/formats/bson/serialize.hpp
4/// @brief Textual serialization helpers
5
6#include <iosfwd>
7#include <string>
8#include <string_view>
9
10#include <fmt/core.h>
11
12#include <userver/compiler/select.hpp>
13#include <userver/formats/bson/document.hpp>
14#include <userver/formats/bson/value.hpp>
15#include <userver/formats/json_fwd.hpp>
16#include <userver/logging/log_helper_fwd.hpp>
17#include <userver/utils/fast_pimpl.hpp>
18#include <userver/utils/fmt_compat.hpp>
19
20USERVER_NAMESPACE_BEGIN
21
22namespace formats::parse {
23
24/// @brief Converts a BSON value to JSON format with type conversions
25///
26/// Performs format conversion with special handling for BSON-specific types:
27/// - BSON Timestamp → int64 (milliseconds since epoch)
28/// - BSON Decimal128 → string representation
29/// - BSON Oid → string representation
30/// - BSON Binary → string representation
31/// - BSON MinKey → JSON object `{"$minKey": 1}`
32/// - BSON MaxKey → JSON object `{"$maxKey": 1}`
33/// - Basic types (bool, int32, int64, double, string, datetime) are preserved
34/// - Arrays and objects are recursively converted
35///
36/// @throws formats::bson::ConversionException if the BSON value contains
37/// an unknown type that cannot be converted to JSON
38formats::json::Value Convert(const formats::bson::Value& bson, formats::parse::To<formats::json::Value>);
39
40/// @brief Converts a JSON value to BSON format
41///
42/// Performs a minimal format conversion that preserves basic types
43/// (bool, int, int64, uint64, double, string, null, arrays, objects).
44/// Missing JSON values are converted to BSON null.
45formats::bson::Value Convert(const formats::json::Value& json, formats::parse::To<formats::bson::Value>);
46
47/// @brief Converts a BSON value to JSON format (minimal conversion)
48///
49/// Performs a minimal format conversion that only handles basic types
50/// common to both BSON and JSON (bool, int, int64, uint64, double, string,
51/// null, arrays, objects).
52///
53/// @warning BSON-specific types (Timestamp, Decimal128, Oid, Binary, MinKey,
54/// MaxKey, etc.) are NOT supported by this function. For converting
55/// BSON documents with these types, use Convert() instead, which
56/// provides proper type conversions.
57///
58/// @throws formats::bson::Exception if the BSON value is missing or contains
59/// an unknown/unsupported node type (e.g., BSON-specific types like
60/// Timestamp, Oid, Binary, etc.)
61formats::json::Value Parse(const formats::bson::Value& bson, formats::parse::To<formats::json::Value>);
62
63/// @brief Converts a JSON value to BSON format (minimal conversion)
64///
65/// Performs a minimal format conversion that preserves the structure and basic
66/// types (bool, int, int64, uint64, double, string, null, arrays, objects).
67///
68/// @throws formats::json::Exception if the JSON value is missing or contains
69/// an unknown node type that cannot be converted to BSON
70formats::bson::Value Parse(const formats::json::Value& json, formats::parse::To<formats::bson::Value>);
71
72} // namespace formats::parse
73
74namespace formats::bson {
75
76/// Wraps To*JsonString results to avoid unneeded copying
77class JsonString;
78
79/// Applies heuristics to convert JSON string to BSON document.
80/// As JSON have rather lax typing, some heuristics are applied to guess correct
81/// BSON types for values. It is strongly recommended to write your own
82/// conversion routines matching your schemas.
83/// @warning Stability of heuristics is not guaranteed, this is provided as-is.
84Document FromJsonString(std::string_view json);
85
86/// Applies heuristics to convert JSON string to BSON array.
87/// As JSON have rather lax typing, some heuristics are applied to guess correct
88/// BSON types for values. It is strongly recommended to write your own
89/// conversion routines matching your schemas.
90/// @warning Stability of heuristics is not guaranteed, this is provided as-is.
91Value ArrayFromJsonString(std::string_view json);
92
93/// Converts BSON to a canonical MongoDB Extended JSON format.
94/// @see
95/// https://github.com/mongodb/specifications/blob/master/source/extended-json.rst
97
98/// Converts BSON to a relaxed MongoDB Extended JSON format.
99/// Notable differences from canonical format are:
100/// * numbers are not being wrapped in `$number*` objects;
101/// * dates have string representation.
102/// @see
103/// https://github.com/mongodb/specifications/blob/master/source/extended-json.rst
105
106/// Converts BSON to a legacy libbson's JSON format.
107/// Notable differences from other formats:
108/// * all numbers are not wrapped;
109/// * non-standard tokens for special floating point values;
110/// * dates are milliseconds since epoch;
111/// * different format for binaries.
113
114/// Converts BSON array to a legacy libbson's JSON format, except the outermost
115/// element is encoded as a JSON array, rather than a JSON document.
117
118namespace impl {
119class JsonStringImpl;
120} // namespace impl
121
123public:
124 /// @cond
125 explicit JsonString(impl::JsonStringImpl&&);
126 /// @endcond
127 ~JsonString();
128
129 /// Implicitly convertible to string
130 /*implicit*/ operator std::string() const { return ToString(); }
131
132 /// Returns a copy of the string
133 std::string ToString() const;
134
135 /// Returns a view of the string
136 std::string_view GetView() const;
137
138 const char* Data() const;
139 size_t Size() const;
140
141private:
142 static constexpr std::size_t kSize =
143 compiler::SelectSize() //
144 .For64Bit(16)
145 .For32Bit(8);
146 static constexpr std::size_t kAlignment = alignof(void*);
147 utils::FastPimpl<impl::JsonStringImpl, kSize, kAlignment, utils::kStrictMatch> impl_;
148};
149
150std::ostream& operator<<(std::ostream&, const JsonString&);
151
152logging::LogHelper& operator<<(logging::LogHelper&, const JsonString&);
153
154/// Uses formats::bson::ToRelaxedJsonString representation by default.
155logging::LogHelper& operator<<(logging::LogHelper&, const Document&);
156
157} // namespace formats::bson
158
159USERVER_NAMESPACE_END
160
161template <>
162struct fmt::formatter<USERVER_NAMESPACE::formats::bson::JsonString> : public fmt::formatter<std::string_view> {
163 template <typename FormatContext>
164 auto format(const USERVER_NAMESPACE::formats::bson::JsonString& json, FormatContext& ctx) USERVER_FMT_CONST {
165 return fmt::formatter<std::string_view>::format(json.GetView(), ctx);
166 }
167};
168
169/// Uses formats::bson::ToRelaxedJsonString representation by default.
170template <>
171struct fmt::formatter<USERVER_NAMESPACE::formats::bson::Document> : public fmt::formatter<std::string_view> {
172 template <typename FormatContext>
173 auto format(const USERVER_NAMESPACE::formats::bson::Document& bson, FormatContext& ctx) USERVER_FMT_CONST {
174 return fmt::formatter<
175 std::string_view>::format(USERVER_NAMESPACE::formats::bson::ToRelaxedJsonString(bson).GetView(), ctx);
176 }
177};