From 32f4d5564ea7dc9f595b446a8651f731f11a5386 Mon Sep 17 00:00:00 2001 From: "Dr. Colin Hirsch" Date: Mon, 18 Sep 2023 16:22:57 +0200 Subject: [PATCH] Fix #146. --- include/tao/json/binding/internal/object.hpp | 15 ++++++++----- src/test/json/binding_object.cpp | 23 +++++++++++++++++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/tao/json/binding/internal/object.hpp b/include/tao/json/binding/internal/object.hpp index c0342dfd..e08edc60 100644 --- a/include/tao/json/binding/internal/object.hpp +++ b/include/tao/json/binding/internal/object.hpp @@ -136,6 +136,12 @@ namespace tao::json::binding::internal } } + template< typename A, template< typename... > class Traits, typename C > + [[nodiscard]] static bool require_encode( const C& x ) + { + return ( N == for_nothing_value::encode ) || ( A::kind == member_kind::required ) || ( !A::template is_nothing< Traits >( x ) ); + } + #if defined( _MSC_VER ) #pragma warning( push ) #pragma warning( disable : 4127 ) @@ -143,7 +149,7 @@ namespace tao::json::binding::internal template< typename A, template< typename... > class Traits, typename C > static void assign_member( basic_value< Traits >& v, const C& x ) { - if( ( N == for_nothing_value::encode ) || ( !A::template is_nothing< Traits >( x ) ) ) { + if( require_encode< A, Traits >( x ) ) { v.try_emplace( A::template key< Traits >(), A::read( x ) ); } } @@ -199,10 +205,7 @@ namespace tao::json::binding::internal template< template< typename... > class Traits, typename C > [[nodiscard]] static std::size_t produce_size( const C& x ) { - if constexpr( N == for_nothing_value::encode ) { - return sizeof...( As ); - } - return ( std::size_t( !As::template is_nothing< Traits >( x ) ) + ... ); + return ( std::size_t( require_encode< As, Traits >( x ) ) + ... ); } #if defined( _MSC_VER ) @@ -213,7 +216,7 @@ namespace tao::json::binding::internal template< typename A, template< typename... > class Traits, typename Consumer, typename C > static void produce_member( Consumer& consumer, const C& x ) { - if( ( N == for_nothing_value::encode ) || ( !A::template is_nothing< Traits >( x ) ) ) { + if( require_encode< A, Traits >( x ) ) { A::template produce_key< Traits >( consumer ); A::template produce< Traits >( consumer, x ); consumer.member(); diff --git a/src/test/json/binding_object.cpp b/src/test/json/binding_object.cpp index 09a17a75..7eee82c4 100644 --- a/src/test/json/binding_object.cpp +++ b/src/test/json/binding_object.cpp @@ -4,6 +4,7 @@ #include "test.hpp" #include +#include namespace tao::json { @@ -212,7 +213,26 @@ namespace tao::json TEST_ASSERT( s.i == 42 ); } - // TODO: Test with different for_nothing_value (incl. consistency of size to consumer). + struct type_7 + { + std::vector< int > a; + std::vector< int > b; + }; + + template<> + struct traits< type_7 > + : binding::basic_object< binding::for_unknown_key::fail, + binding::for_nothing_value::suppress, + TAO_JSON_BIND_REQUIRED( "a", &type_7::a ), + TAO_JSON_BIND_OPTIONAL( "b", &type_7::b ) > + {}; + + void unit_test_7() + { + const type_7 t; + const auto s = produce::to_string( t ); + TEST_ASSERT( s == "{\"a\":[]}" ); + } void unit_test() { @@ -222,6 +242,7 @@ namespace tao::json unit_test_4(); unit_test_5(); unit_test_6(); + unit_test_7(); } } // namespace tao::json