DAW JSON Link
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 
11 #include "impl/version.h"
12 
14 #include "daw_to_json_fwd.h"
18 
19 #include <daw/daw_traits.h>
20 
21 #include <iterator>
22 #include <string>
23 #include <string_view>
24 #include <type_traits>
25 
26 namespace daw::json {
27  inline namespace DAW_JSON_VER {
28  namespace json_details {
29  template<typename output_t, auto... PolicyFlags, typename WritableType>
30  DAW_ATTRIB_INLINE constexpr auto apply_policy_flags( WritableType &&it ) {
31  if constexpr( is_serialization_policy_v<
32  daw::remove_cvref_t<WritableType>> ) {
33  if constexpr( sizeof...( PolicyFlags ) == 0 ) {
34  return it;
35  } else {
36  return serialization_policy<typename output_t::iterator_type,
37  json_details::serialization::set_bits(
38  output_t::policy_flags( ),
39  PolicyFlags... )>( it.get( ) );
40  }
41  } else {
42  return serialization_policy<
43  daw::remove_cvref_t<WritableType>,
44  options::output_flags_t<PolicyFlags...>::value>( it );
45  }
46  }
47  } // namespace json_details
48 
49  template<typename JsonClass, typename Value, typename WritableType,
50  auto... PolicyFlags DAW_JSON_ENABLEIF2(
52  daw::remove_cvref_t<WritableType>> )>
54  concepts::is_writable_output_type_v<daw::remove_cvref_t<WritableType>> )
55  constexpr daw::rvalue_to_value_t<WritableType> to_json(
56  Value const &value, WritableType &&it,
57  options::output_flags_t<PolicyFlags...> ) {
58 
59  using json_class_t = typename daw::conditional_t<
60  std::is_same_v<use_default, JsonClass>,
61  json_details::ident_trait<json_details::json_deduced_type, Value>,
62  json_details::ident_trait<json_details::json_deduced_type,
63  JsonClass>>::type;
64 
65  using output_t = daw::rvalue_to_value_t<WritableType>;
66  if constexpr( std::is_pointer_v<daw::remove_cvref_t<WritableType>> ) {
67  daw_json_ensure( it != nullptr, ErrorReason::NullOutputIterator );
68  }
69  auto out_it =
70  json_details::apply_policy_flags<output_t, PolicyFlags...>( it );
71 
72  return json_details::member_to_string<json_class_t>( out_it, value )
73  .get( );
74  }
75 
76  template<typename JsonClass, typename Value, auto... PolicyFlags>
77  inline std::string to_json( Value const &value,
78  options::output_flags_t<PolicyFlags...> flgs ) {
79  std::string result{ };
80  result.reserve( 4096 );
81  (void)to_json( value, result, flgs );
82  result.shrink_to_fit( );
83  return result;
84  }
85 
86  template<typename JsonElement, typename Container, typename WritableType,
87  auto... PolicyFlags DAW_JSON_ENABLEIF2(
89  daw::remove_cvref_t<WritableType>> )>
91  concepts::is_writable_output_type_v<daw::remove_cvref_t<WritableType>> )
92  constexpr daw::rvalue_to_value_t<WritableType> to_json_array(
93  Container const &c, WritableType &&it,
94  options::output_flags_t<PolicyFlags...> ) {
95  static_assert(
96  daw::traits::is_container_like_v<daw::remove_cvref_t<Container>>,
97  "Supplied container must support begin( )/end( )" );
98  using output_t = daw::rvalue_to_value_t<WritableType>;
99 
100  if constexpr( std::is_pointer_v<daw::remove_cvref_t<output_t>> ) {
101  daw_json_ensure( it != nullptr, ErrorReason::InvalidNull );
102  }
103  auto out_it = [&] {
104  if constexpr( is_serialization_policy_v<
105  daw::remove_cvref_t<WritableType>> ) {
106  if constexpr( sizeof...( PolicyFlags ) == 0 ) {
107  return it;
108  } else {
109  return serialization_policy<typename output_t::iterator_type,
110  json_details::serialization::set_bits(
111  output_t::policy_flags( ),
112  PolicyFlags... )>( it.get( ) );
113  }
114  } else {
115  return serialization_policy<
116  daw::remove_cvref_t<WritableType>,
117  options::output_flags_t<PolicyFlags...>::value>( it );
118  }
119  }( );
120  out_it.put( '[' );
121  out_it.add_indent( );
122  // Not const & as some types(vector<bool>::const_reference are not ref
123  // types
124  auto first = std::begin( c );
125  auto last = std::end( c );
126  bool const has_elements = first != last;
127  while( first != last ) {
128  (void)[&out_it]( auto &&v ) {
129  using v_type = DAW_TYPEOF( v );
130  using JsonMember = typename daw::conditional_t<
131  std::is_same_v<JsonElement, use_default>,
132  json_details::ident_trait<json_details::json_deduced_type, v_type>,
133  json_details::ident_trait<json_details::json_deduced_type,
134  JsonElement>>::type;
135 
136  static_assert(
137  not std::is_same_v<
138  JsonMember,
139  missing_json_data_contract_for_or_unknown_type<JsonElement>>,
140  "Unable to detect unnamed mapping" );
141  // static_assert( not std::is_same_v<JsonElement, JsonMember> );
142  out_it.next_member( );
143 
144  out_it = json_details::member_to_string<JsonMember>( out_it, v );
145  }
146  ( *first );
147  ++first;
148  if( first != last ) {
149  out_it.put( ',' );
150  }
151  }
152  // The last character will be a ',' prior to this
153  out_it.del_indent( );
154  if( has_elements ) {
155  out_it.output_newline( );
156  }
157  out_it.put( ']' );
158  return out_it.get( );
159  }
160 
161  template<typename JsonElement, typename Container, auto... PolicyFlags>
162  inline std::string
163  to_json_array( Container const &c,
164  options::output_flags_t<PolicyFlags...> flgs ) {
165  static_assert( not std::is_same_v<std::string, JsonElement> );
166  std::string result{ };
167  result.reserve( 4096 );
168  (void)to_json_array( c, result, flgs );
169  result.shrink_to_fit( );
170  return result;
171  }
172  } // namespace DAW_JSON_VER
173 } // namespace daw::json
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
#define DAW_JSON_ENABLEIF2(...)
std::string to_json(Value const &value, options::output_flags_t< PolicyFlags... > flgs)
Definition: daw_to_json.h:77
std::string to_json_array(Container const &c, options::output_flags_t< PolicyFlags... > flgs)
Definition: daw_to_json.h:163
Customization point traits.
DAW_JSON_REQUIRES(boost::describe::has_describe_members< T >::value and use_boost_describe_v< T >) struct json_data_contract< T >
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:25