userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
write_to_stream.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/formats/serialize/write_to_stream.hpp
4
/// @brief Common WriteToStream functions for SAX serializers.
5
/// @ingroup userver_universal userver_formats_serialize_sax
6
7
#
include
<
map
>
8
#
include
<
optional
>
9
#
include
<
type_traits
>
10
#
include
<
unordered_map
>
11
#
include
<
variant
>
12
13
#
include
<
userver
/
utils
/
meta
.
hpp
>
14
15
#
include
<
userver
/
formats
/
common
/
meta
.
hpp
>
16
17
namespace
boost::
uuids
{
18
struct
uuid;
19
}
20
21
USERVER_NAMESPACE_BEGIN
22
23
namespace
utils
::impl::strong_typedef {
24
struct
StrongTypedefTag;
25
}
26
27
namespace
formats::
serialize
{
28
29
/// An ADL helper that allows searching for `WriteToStream` functions in
30
/// namespace of the stream. Derive your SAX string builder from this type.
31
struct
SaxStream
{};
32
33
/// Variant serialization
34
template
<
typename
... Types,
typename
StringBuilder>
35
void
WriteToStream
(
const
std::variant<Types...>& value, StringBuilder& sw) {
36
return
std::visit([&sw](
const
auto
& item) { WriteToStream(item, sw); }, value);
37
}
38
39
/// std::optional serialization
40
template
<
typename
T,
typename
StringBuilder>
41
void
WriteToStream
(
const
std::optional<T>& value, StringBuilder& sw) {
42
if
(!value) {
43
sw.WriteNull();
44
return
;
45
}
46
47
WriteToStream(*value, sw);
48
}
49
50
namespace
impl {
51
52
// We specialize kIsSerializeAllowedInWriteToStream to catch the usages of
53
// Serialize for your type. Make sure that kIsSerializeAllowedInWriteToStream is
54
// visible at the point of WriteToStream instantiation.
55
template
<
class
T,
class
StringBuilder>
56
constexpr
inline
bool
kIsSerializeAllowedInWriteToStream =
true
;
57
58
// Array like types serialization
59
template
<
typename
T,
typename
StringBuilder>
60
void
WriteToStreamArray(
const
T& value, StringBuilder& sw) {
61
const
typename
StringBuilder::ArrayGuard guard(sw);
62
for
(
const
auto
& item : value) {
63
// explicit cast for vector<bool> shenanigans
64
WriteToStream(
static_cast
<
const
meta::
RangeValueType
<T>&>(item), sw);
65
}
66
}
67
68
// Dict like types serialization
69
template
<
typename
T,
typename
StringBuilder>
70
void
WriteToStreamDict(
const
T& value, StringBuilder& sw) {
71
const
typename
StringBuilder::ObjectGuard guard(sw);
72
for
(
const
auto
& [key, item] : value) {
73
sw.Key(key);
74
WriteToStream(item, sw);
75
}
76
}
77
78
}
// namespace impl
79
80
/// Handle ranges, fall back to using formats::*::Serialize
81
///
82
/// The signature of this WriteToStream must remain the less specialized one, so
83
/// that it is not preferred over other functions.
84
template
<
typename
T,
typename
StringBuilder>
85
requires
(!std::is_arithmetic_v<T> && !std::is_convertible_v<T&,
utils
::impl::strong_typedef::StrongTypedefTag&>)
86
void
WriteToStream
(
const
T& value, StringBuilder& sw) {
87
using
Value =
typename
StringBuilder::Value;
88
89
if
constexpr
(meta::
kIsMap
<T>) {
90
impl::WriteToStreamDict(value, sw);
91
}
else
if
constexpr
(meta::
kIsRange
<T>) {
92
static_assert
(
93
!std::is_same_v<T, boost::
uuids
::uuid>,
94
"Include <userver/formats/serialize/boost_uuid.hpp> to serialize 'boost::uuids::uuid"
95
);
96
static_assert
(
97
!meta::
IsRecursiveRange
<T>,
98
"Trying to log a recursive range, which can be dangerous. "
99
"(boost::filesystem::path?) Please implement WriteToStream for your type"
100
);
101
impl::WriteToStreamArray(value, sw);
102
}
else
if
constexpr
(common::impl::HasSerialize<Value, T>) {
103
static_assert
(
104
!
sizeof
(T) || impl::kIsSerializeAllowedInWriteToStream<T, StringBuilder>,
105
"SAX serialization falls back to Serialize call, which is not "
106
"allowed. Please implement WriteToStream for your type"
107
);
108
sw.WriteValue(Serialize(value,
serialize
::
To
<Value>{}));
109
}
else
{
110
static_assert
(!
sizeof
(T),
"Please implement WriteToStream or Serialize for your type"
);
111
}
112
}
113
114
}
// namespace formats::serialize
115
116
USERVER_NAMESPACE_END
userver
formats
serialize
write_to_stream.hpp
Generated on
for userver by
Doxygen
1.17.0