10#include <unordered_map>
13#include <userver/utils/meta.hpp>
15#include <userver/formats/common/meta.hpp>
17USERVER_NAMESPACE_BEGIN
26template <
typename... Types,
typename StringBuilder>
27void WriteToStream(
const std::variant<Types...>& value, StringBuilder& sw) {
28 return std::visit([&sw](
const auto& item) { WriteToStream(item, sw); },
33template <
typename T,
typename StringBuilder>
40 WriteToStream(*value, sw);
48template <
class T,
class StringBuilder>
49constexpr inline bool kIsSerializeAllowedInWriteToStream =
true;
52template <
typename T,
typename StringBuilder>
53void WriteToStreamArray(
const T& value, StringBuilder& sw) {
54 typename StringBuilder::ArrayGuard guard(sw);
55 for (
const auto& item : value) {
57 WriteToStream(
static_cast<
const meta::RangeValueType<T>&>(item), sw);
62template <
typename T,
typename StringBuilder>
63void WriteToStreamDict(
const T& value, StringBuilder& sw) {
64 typename StringBuilder::ObjectGuard guard(sw);
65 for (
const auto& [key, value] : value) {
67 WriteToStream(value, sw);
77template <
typename T,
typename StringBuilder>
80 using Value =
typename StringBuilder::Value;
82 if constexpr (meta::kIsMap<T>) {
83 impl::WriteToStreamDict(value, sw);
84 }
else if constexpr (meta::kIsRange<T>) {
85 static_assert(!meta::kIsRecursiveRange<T>,
86 "Trying to log a recursive range, which can be dangerous. "
87 "(boost::filesystem::path?) Please implement WriteToStream "
89 impl::WriteToStreamArray(value, sw);
90 }
else if constexpr (
common::impl::kHasSerialize<Value, T>) {
93 impl::kIsSerializeAllowedInWriteToStream<T, StringBuilder>,
94 "SAX serialization falls back to Serialize call, which is not "
95 "allowed. Please implement WriteToStream for your type");
96 sw.WriteValue(Serialize(value,
serialize::
To<Value>{}));
98 static_assert(!
sizeof(T),
99 "Please implement WriteToStream or Serialize for your type");