From 7e7da210a76e7d1474ce0a2c6df6b76a23ca438e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 12 Mar 2024 18:11:30 +0100 Subject: [PATCH] Allow easy printing ranges of objects --- nano/core_test/object_stream.cpp | 34 +++++++++++++++++++- nano/lib/object_stream.hpp | 3 +- nano/lib/object_stream_adapters.hpp | 49 +++++++++++++++++++++-------- 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/nano/core_test/object_stream.cpp b/nano/core_test/object_stream.cpp index ead8bad719..11f14922ff 100644 --- a/nano/core_test/object_stream.cpp +++ b/nano/core_test/object_stream.cpp @@ -556,4 +556,36 @@ TEST (object_stream, to_json) )"); ASSERT_EQ (str, expected); -} \ No newline at end of file +} + +TEST (object_stream, print_range) +{ + std::deque objects; + objects.push_back ({ 1 }); + objects.push_back ({ 2 }); + objects.push_back ({ 3 }); + + std::stringstream ss1, ss2; + ss1 << nano::streamed_range (objects); + ss2 << fmt::format ("{}", nano::streamed_range (objects)); + + auto expected = trim (R"( +[ + { + uint256_union_field: "0000000000000000000000000000000000000000000000000000000000000001", + block_hash: "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + uint256_union_field: "0000000000000000000000000000000000000000000000000000000000000002", + block_hash: "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + uint256_union_field: "0000000000000000000000000000000000000000000000000000000000000003", + block_hash: "0000000000000000000000000000000000000000000000000000000000000000" + } +] +)"); + + ASSERT_EQ (ss1.str (), expected); + ASSERT_EQ (ss2.str (), expected); +} diff --git a/nano/lib/object_stream.hpp b/nano/lib/object_stream.hpp index 40c638df91..f51e6feb06 100644 --- a/nano/lib/object_stream.hpp +++ b/nano/lib/object_stream.hpp @@ -281,7 +281,7 @@ class array_stream : private object_stream_base array_stream (array_stream const &) = delete; // Disallow copying -private: +public: template void write_single (Value const & value) { @@ -290,7 +290,6 @@ class array_stream : private object_stream_base ctx.end_array_element (); } -public: // Handle `.write (container)` template void write (Container const & container) diff --git a/nano/lib/object_stream_adapters.hpp b/nano/lib/object_stream_adapters.hpp index 8be5b445f4..29e372c86d 100644 --- a/nano/lib/object_stream_adapters.hpp +++ b/nano/lib/object_stream_adapters.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -9,42 +10,64 @@ namespace nano { -template +template struct object_stream_formatter { nano::object_stream_config const & config; Streamable const & value; + Writer writer; - explicit object_stream_formatter (Streamable const & value, nano::object_stream_config const & config) : + explicit object_stream_formatter (Streamable const & value, Writer writer, nano::object_stream_config const & config) : config{ config }, - value{ value } + value{ value }, + writer{ writer } { } - friend std::ostream & operator<< (std::ostream & os, object_stream_formatter const & self) + friend std::ostream & operator<< (std::ostream & os, object_stream_formatter const & self) { nano::root_object_stream obs{ os, self.config }; - obs.write (self.value); + self.writer (self.value, obs); return os; } // Needed for fmt formatting, uses the ostream operator under the hood - friend auto format_as (object_stream_formatter const & val) + friend auto format_as (object_stream_formatter const & self) { - return fmt::streamed (val); + return fmt::streamed (self); } }; -template -auto streamed (Streamable const & value) +enum class streamed_format +{ + basic, + json +}; + +inline nano::object_stream_config const & to_object_stream_config (streamed_format format) { - return object_stream_formatter{ value, nano::object_stream_config::default_config () }; + switch (format) + { + case streamed_format::basic: + return nano::object_stream_config::default_config (); + case streamed_format::json: + return nano::object_stream_config::json_config (); + default: + debug_assert (false); + return nano::object_stream_config::default_config (); + } } template -auto streamed_as_json (Streamable const & value) +auto streamed (Streamable const & value, streamed_format format = streamed_format::basic) +{ + return object_stream_formatter{ value, [] (auto const & value, nano::root_object_stream & obs) { obs.write (value); }, to_object_stream_config (format) }; +} + +template +auto streamed_range (StreamableRange const & value, streamed_format format = streamed_format::basic) { - return object_stream_formatter{ value, nano::object_stream_config::json_config () }; + return object_stream_formatter{ value, [] (auto const & value, nano::root_object_stream & obs) { obs.write_range (value); }, to_object_stream_config (format) }; } /** @@ -109,7 +132,7 @@ template std::string to_json (Value const & value) { std::stringstream ss; - ss << nano::streamed_as_json (value); + ss << nano::streamed (value, nano::streamed_format::json); return ss.str (); } }