10#include <unordered_map>
13#include <userver/utils/meta.hpp>
15#include <userver/formats/common/meta.hpp>
17USERVER_NAMESPACE_BEGIN
19namespace utils::impl::strong_typedef {
20struct StrongTypedefTag;
30template <
typename... Types,
typename StringBuilder>
31void WriteToStream(
const std::variant<Types...>& value, StringBuilder& sw) {
32 return std::visit([&sw](
const auto& item) { WriteToStream(item, sw); }, value);
36template <
typename T,
typename StringBuilder>
43 WriteToStream(*value, sw);
51template <
class T,
class StringBuilder>
52constexpr inline bool kIsSerializeAllowedInWriteToStream =
true;
55template <
typename T,
typename StringBuilder>
56void WriteToStreamArray(
const T& value, StringBuilder& sw) {
57 typename StringBuilder::ArrayGuard guard(sw);
58 for (
const auto& item : value) {
60 WriteToStream(
static_cast<
const meta::RangeValueType<T>&>(item), sw);
65template <
typename T,
typename StringBuilder>
66void WriteToStreamDict(
const T& value, StringBuilder& sw) {
67 typename StringBuilder::ObjectGuard guard(sw);
68 for (
const auto& [key, item] : value) {
70 WriteToStream(item, sw);
80template <
typename T,
typename StringBuilder>
83 using Value =
typename StringBuilder::Value;
85 if constexpr (meta::kIsMap<T>) {
86 impl::WriteToStreamDict(value, sw);
87 }
else if constexpr (meta::kIsRange<T>) {
89 !meta::kIsRecursiveRange<T>,
90 "Trying to log a recursive range, which can be dangerous. "
91 "(boost::filesystem::path?) Please implement WriteToStream "
94 impl::WriteToStreamArray(value, sw);
95 }
else if constexpr (
common::impl::kHasSerialize<Value, T>) {
97 !
sizeof(T) || impl::kIsSerializeAllowedInWriteToStream<T, StringBuilder>,
98 "SAX serialization falls back to Serialize call, which is not "
99 "allowed. Please implement WriteToStream for your type"
101 sw.WriteValue(Serialize(value,
serialize::
To<Value>{}));
103 static_assert(!
sizeof(T),
"Please implement WriteToStream or Serialize for your type");