DAW JSON Link
Loading...
Searching...
No Matches
daw_to_json.h
Go to the documentation of this file.
1// Copyright (c) Darrell Wright
2//
3// Distributed under the Boost Software License, version 1.0. (see accompanying
4// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// Official repository: https://github.com/beached/daw_json_link
7//
8
9#pragma once
10
12
18
19#include <daw/daw_enable_requires.h>
20#include <daw/daw_span.h>
21#include <daw/daw_string_view.h>
22#include <daw/daw_traits.h>
23
24#include <iterator>
25#include <optional>
26#include <string>
27#include <type_traits>
28#include <utility>
29
30namespace daw::json {
31 inline namespace DAW_JSON_VER {
32 namespace json_details {
33 template<typename output_t, auto... PolicyFlags, typename WritableType>
34 DAW_ATTRIB_INLINE constexpr auto apply_policy_flags( WritableType &&it ) {
35 if constexpr( is_serialization_policy_v<
36 daw::remove_cvref_t<WritableType>> ) {
37 if constexpr( sizeof...( PolicyFlags ) == 0 ) {
38 return it;
39 } else {
40 return serialization_policy<typename output_t::iterator_type,
41 json_details::serialization::set_bits(
42 output_t::policy_flags( ),
43 PolicyFlags... )>( it.get( ) );
44 }
45 } else {
47 daw::remove_cvref_t<WritableType>,
48 options::output_flags_t<PolicyFlags...>::value>( it );
49 }
50 }
51 } // namespace json_details
52
53 template<
54 typename JsonClass, typename Value, typename WritableType,
55 auto... PolicyFlags DAW_ENABLEIF2( concepts::is_writable_output_type_v<
56 daw::remove_cvref_t<WritableType>> )>
58 concepts::is_writable_output_type_v<daw::remove_cvref_t<WritableType>> )
59 constexpr daw::rvalue_to_value_t<WritableType> to_json(
60 Value const &value, WritableType &&it,
61 options::output_flags_t<PolicyFlags...> flags ) {
62 if constexpr( json_details::is_char_pointer_v<Value> ) {
63 // A nul terminated string, nullptr is null. An explicit JsonClass
64 // is given the string_view
65 if( value == nullptr ) {
66 return to_json<use_default>(
67 std::optional<daw::string_view>( ), DAW_FWD( it ), flags );
68 }
69 return to_json<JsonClass>(
70 daw::string_view( value ), DAW_FWD( it ), flags );
71 } else if constexpr( json_details::is_char_array_v<Value> ) {
72 // Exclude the trailing nul. An explicit JsonClass is given the
73 // string_view
74 return to_json<JsonClass>(
75 daw::string_view( value, std::extent_v<Value> - 1U ),
76 DAW_FWD( it ),
77 flags );
78 } else {
79 using json_class_t =
80 json_details::json_serialize_deduced_type<JsonClass, Value>;
81
82 using output_t = daw::rvalue_to_value_t<WritableType>;
83 if constexpr( std::is_pointer_v<daw::remove_cvref_t<WritableType>> ) {
84 daw_json_ensure( it != nullptr, ErrorReason::NullOutputIterator );
85 }
86 auto out_it =
87 json_details::apply_policy_flags<output_t, PolicyFlags...>( it );
88
89 out_it = json_details::member_to_string<json_class_t>( out_it, value );
90 return out_it.get( );
91 }
92 }
93
94 template<typename JsonClass, typename Value, auto... PolicyFlags>
95 DAW_CPP20_CX_ALLOC std::string
96 to_json( Value const &value,
97 options::output_flags_t<PolicyFlags...> flgs ) {
98 auto out = string_writer( );
99 (void)to_json<JsonClass>( value, out, flgs );
100 return std::move( out ).finish( );
101 }
102
103 namespace json_details {
104 template<auto... PolicyFlags, typename WritableType>
105 constexpr auto make_output_iterator( WritableType &&it ) {
106 using output_t = daw::rvalue_to_value_t<WritableType>;
107
108 if constexpr( std::is_pointer_v<daw::remove_cvref_t<output_t>> ) {
109 daw_json_ensure( it != nullptr, ErrorReason::InvalidNull );
110 }
111 if constexpr( is_serialization_policy_v<
112 daw::remove_cvref_t<WritableType>> ) {
113 if constexpr( sizeof...( PolicyFlags ) == 0 ) {
114 return it;
115 } else {
116 return serialization_policy<typename output_t::iterator_type,
117 json_details::serialization::set_bits(
118 output_t::policy_flags( ),
119 PolicyFlags... )>( it.get( ) );
120 }
121 } else {
122 return serialization_policy<
123 daw::remove_cvref_t<WritableType>,
124 options::output_flags_t<PolicyFlags...>::value>( it );
125 }
126 }
127 } // namespace json_details
128
129 template<
130 typename JsonElement, typename Container, typename WritableType,
131 auto... PolicyFlags DAW_ENABLEIF2( concepts::is_writable_output_type_v<
132 daw::remove_cvref_t<WritableType>> )>
134 concepts::is_writable_output_type_v<daw::remove_cvref_t<WritableType>> )
135 constexpr daw::rvalue_to_value_t<WritableType> to_json_array(
136 Container const &c, WritableType &&it,
137 options::output_flags_t<PolicyFlags...> flags ) {
138 if constexpr( json_details::is_char_array_v<Container> ) {
139 // Exclude the trailing nul, same as to_json and json_writer
140 return to_json_array<JsonElement>(
141 daw::string_view( c, std::extent_v<Container> - 1U ),
142 DAW_FWD( it ),
143 flags );
144 } else if constexpr( std::is_array_v<Container> ) {
145 return to_json_array<JsonElement>(
146 daw::span<std::remove_extent_t<Container> const>(
147 c, std::extent_v<Container> ),
148 DAW_FWD( it ),
149 flags );
150 } else if constexpr( std::is_pointer_v<Container> ) {
151 static_assert( daw::deduced_false_v<Container>,
152 "Pointers have no length, pass a span or container" );
153 } else {
154 static_assert(
155 daw::traits::is_container_like_v<daw::remove_cvref_t<Container>>,
156 "Supplied container must support begin( )/end( )" );
157
158 auto out_it =
159 json_details::make_output_iterator<PolicyFlags...>( DAW_FWD( it ) );
160 json_details::reserve_array_output<
161 json_details::json_serialize_deduced_type<
162 JsonElement, daw::remove_cvref_t<decltype( *std::begin( c ) )>>>(
163 out_it, c );
164 out_it.put( '[' );
165 out_it.add_indent( );
166 // Not const & as some types(vector<bool>::const_reference are not ref
167 // types
168 auto first = std::begin( c );
169 auto last = std::end( c );
170 bool const has_elements = first != last;
171 while( first != last ) {
172 (void)[&out_it]( auto &&v ) {
173 using v_type = DAW_TYPEOF( v );
174 using JsonMember =
175 json_details::json_serialize_deduced_type<JsonElement, v_type>;
176
177 static_assert(
178 not std::is_same_v<
179 JsonMember,
180 missing_json_data_contract_for_or_unknown_type<JsonElement>>,
181 "Unable to detect unnamed mapping" );
182 // static_assert( not std::is_same_v<JsonElement, JsonMember> );
183 out_it.next_member( );
184
185 out_it = json_details::member_to_string<JsonMember>( out_it, v );
186 }
187 ( *first );
188 ++first;
189 if( first != last ) {
190 out_it.put( ',' );
191 }
192 }
193 // The last character will be a ',' prior to this
194 out_it.del_indent( );
195 if( has_elements ) {
196 out_it.output_newline( );
197 }
198 out_it.put( ']' );
199 return out_it.get( );
200 }
201 }
202
203 template<typename JsonElement, typename Container, auto... PolicyFlags>
204 DAW_CPP20_CX_ALLOC std::string
205 to_json_array( Container const &c,
206 options::output_flags_t<PolicyFlags...> flgs ) {
207 static_assert( not std::is_same_v<std::string, JsonElement> );
208 auto out = string_writer( );
209 (void)to_json_array<JsonElement>( c, out, flgs );
210 return std::move( out ).finish( );
211 }
212 } // namespace DAW_JSON_VER
213} // namespace daw::json
A writable output that serializes into a std::string. The string's own output trait resizes it on eve...
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
DAW_REQUIRES(daw::json::json_details::is_container_opted_into_json_iostreams_v< Container >) std
An opt in ostream interface for containers of types that have JSON mappings.
DAW_CPP20_CX_ALLOC std::string to_json(Value const &value, options::output_flags_t< PolicyFlags... > flgs)
Definition daw_to_json.h:96
DAW_CPP20_CX_ALLOC std::string to_json_array(Container const &c, options::output_flags_t< PolicyFlags... > flgs)
string_writer grows its string with resize_and_overwrite, leaving the new bytes uninitialized,...
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20