aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpavook <pavook@yandex-team.com>2024-07-09 12:33:43 +0300
committerpavook <pavook@yandex-team.com>2024-07-09 13:16:06 +0300
commit2bd5c6081b9738dd32827b1701d2ccf827c147f0 (patch)
treee511b6ccf3df85189f91ff8736e9e661234d5046
parent8143ce442b7dacca63e8c9de09c9d2bc6f905bf7 (diff)
downloadydb-2bd5c6081b9738dd32827b1701d2ccf827c147f0.tar.gz
Add a formatter for YSON-serializable types
c1ba681251a858e2df7f5c5687fe852574a022c7
-rw-r--r--yt/yt/core/misc/unittests/statistics_ut.cpp12
-rw-r--r--yt/yt/core/ya.make1
-rw-r--r--yt/yt/core/yson/format-inl.h24
-rw-r--r--yt/yt/core/yson/format.h29
-rw-r--r--yt/yt/core/yson/string_builder_stream.cpp18
-rw-r--r--yt/yt/core/yson/string_builder_stream.h25
-rw-r--r--yt/yt/core/ytree/serialize.h8
7 files changed, 117 insertions, 0 deletions
diff --git a/yt/yt/core/misc/unittests/statistics_ut.cpp b/yt/yt/core/misc/unittests/statistics_ut.cpp
index 25fa851108..737773e9ca 100644
--- a/yt/yt/core/misc/unittests/statistics_ut.cpp
+++ b/yt/yt/core/misc/unittests/statistics_ut.cpp
@@ -3,6 +3,8 @@
#include <yt/yt/core/misc/statistics.h>
#include <yt/yt/core/misc/protobuf_helpers.h>
+#include <yt/yt/core/yson/format.h>
+
#include <yt/yt/core/ytree/convert.h>
#include <yt/yt/core/ytree/fluent.h>
@@ -11,6 +13,16 @@ namespace NYT {
using namespace NYTree;
using namespace NYson;
+template <>
+struct TYsonFormatTraits<TSummary>
+ : public TYsonTextFormatTraits
+{ };
+
+std::ostream& operator<<(std::ostream& out, const TSummary& summary)
+{
+ return out << ToStringViaBuilder(summary);
+}
+
////////////////////////////////////////////////////////////////////////////////
TEST(TStatistics, Summary)
diff --git a/yt/yt/core/ya.make b/yt/yt/core/ya.make
index 9d37642b6e..83a4017b3d 100644
--- a/yt/yt/core/ya.make
+++ b/yt/yt/core/ya.make
@@ -251,6 +251,7 @@ SRCS(
yson/pull_parser_deserialize.cpp
yson/stream.cpp
yson/string.cpp
+ yson/string_builder_stream.cpp
yson/string_filter.cpp
yson/syntax_checker.cpp
yson/token.cpp
diff --git a/yt/yt/core/yson/format-inl.h b/yt/yt/core/yson/format-inl.h
new file mode 100644
index 0000000000..943c3cd5c6
--- /dev/null
+++ b/yt/yt/core/yson/format-inl.h
@@ -0,0 +1,24 @@
+#ifndef FORMAT_INL_H_
+#error "Direct inclusion of this file is not allowed, include format.h"
+// For the sake of sane code completion.
+#include "format.h"
+#endif
+
+#include "string_builder_stream.h"
+#include "writer.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <NYson::CYsonFormattable T>
+void FormatValue(TStringBuilderBase* builder, const T& value, TStringBuf /*spec*/)
+{
+ TStringBuilderStream stream(builder);
+ NYson::TYsonWriter writer(&stream, NYson::TYsonFormatTraits<T>::YsonFormat);
+ Serialize(value, &writer);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/yt/yt/core/yson/format.h b/yt/yt/core/yson/format.h
index bc5309ecab..ebfc2d119a 100644
--- a/yt/yt/core/yson/format.h
+++ b/yt/yt/core/yson/format.h
@@ -2,6 +2,8 @@
#include "token.h"
+#include <yt/yt/core/ytree/serialize.h>
+
namespace NYT::NYson {
////////////////////////////////////////////////////////////////////////////////
@@ -31,5 +33,32 @@ const ETokenType EntityToken = ETokenType::Hash;
////////////////////////////////////////////////////////////////////////////////
+template <class T>
+struct TYsonFormatTraits
+{
+ constexpr static bool UseYsonFormatter = false;
+};
+
+struct TYsonTextFormatTraits
+{
+ constexpr static bool UseYsonFormatter = true;
+ constexpr static EYsonFormat YsonFormat = EYsonFormat::Text;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+concept CYsonFormattable =
+ NYTree::CYsonSerializable<T> &&
+ TYsonFormatTraits<T>::UseYsonFormatter &&
+ requires {
+ { TYsonFormatTraits<T>::YsonFormat } -> std::same_as<const EYsonFormat&>;
+ };
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT::NYson
+#define FORMAT_INL_H_
+#include "format-inl.h"
+#undef FORMAT_INL_H_
diff --git a/yt/yt/core/yson/string_builder_stream.cpp b/yt/yt/core/yson/string_builder_stream.cpp
new file mode 100644
index 0000000000..8b7fce1a65
--- /dev/null
+++ b/yt/yt/core/yson/string_builder_stream.cpp
@@ -0,0 +1,18 @@
+#include "string_builder_stream.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TStringBuilderStream::TStringBuilderStream(TStringBuilderBase* builder) noexcept
+ : Builder_(builder)
+{ }
+
+void TStringBuilderStream::DoWrite(const void* data, size_t size)
+{
+ Builder_->AppendString(TStringBuf(static_cast<const char*>(data), size));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/yt/yt/core/yson/string_builder_stream.h b/yt/yt/core/yson/string_builder_stream.h
new file mode 100644
index 0000000000..b1e0aa4b14
--- /dev/null
+++ b/yt/yt/core/yson/string_builder_stream.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <library/cpp/yt/string/string_builder.h>
+
+#include <util/stream/output.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TStringBuilderStream final
+ : public IOutputStream
+{
+public:
+ TStringBuilderStream(TStringBuilderBase* builder) noexcept;
+
+private:
+ TStringBuilderBase* Builder_;
+
+ void DoWrite(const void* data, size_t size) final;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/yt/yt/core/ytree/serialize.h b/yt/yt/core/ytree/serialize.h
index e5352f5270..5791c2e16f 100644
--- a/yt/yt/core/ytree/serialize.h
+++ b/yt/yt/core/ytree/serialize.h
@@ -268,6 +268,14 @@ void Deserialize(TStrongTypedef<T, TTag>& value, INodePtr node);
////////////////////////////////////////////////////////////////////////////////
+template <class T, class... TExtraArgs>
+concept CYsonSerializable = requires (const T& value, NYson::IYsonConsumer* consumer, TExtraArgs&&... args)
+{
+ { Serialize(value, consumer, std::forward<TExtraArgs>(args)...) } -> std::same_as<void>;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT::NYTree
#define SERIALIZE_INL_H_