11#include " simdjson.h"
22#include " simdjson/json_builder/json_builder.h"
3+ #include < cstdlib>
34#include < string>
45#include < vector>
56#include < iostream>
@@ -68,8 +69,14 @@ tag_invoke(deserialize_tag, std::type_identity<T>, ondemand::value &val) {
6869 return vec;
6970}
7071
72+
73+ // /
74+ // / For simplicity, the definitions of invoke should be non-overlapping.
75+ // / If we provide both a specialization for a container and a specialization for a user-defined type,
76+ // / which one gets picked is maybe unclear???
77+ // /
7178template <typename T>
72- requires json_builder::UserDefinedType<T>
79+ requires ( json_builder::UserDefinedType<T> && ! PushableContainer<T>)
7380simdjson_result<T>
7481tag_invoke (deserialize_tag, std::type_identity<T>, ondemand::value &val) {
7582 ondemand::object obj;
@@ -79,27 +86,17 @@ tag_invoke(deserialize_tag, std::type_identity<T>, ondemand::value &val) {
7986 }
8087 T t;
8188 [:json_builder::expand (std::meta::nonstatic_data_members_of (^T)):] >> [&]<auto mem> {
82- auto it = obj[to_string_view (std::meta::identifier_of (mem) )];
89+ auto it = obj[(std::string_view) std:: meta::identifier_of (mem)];
8390 using MemberType = typename std::remove_reference_t <decltype (t.[:mem:])>;
8491
8592 if constexpr (std::is_same_v<MemberType, int >) {
86- auto int_result = it.get_int64 ();
87- if (int_result.error ()) throw std::runtime_error (" Error getting int64" );
88- t.[:mem:] = static_cast <int >(int_result.value ());
89- } else if constexpr (std::is_same_v<MemberType, double >) {
90- auto double_result = it.get_double ();
91- if (double_result.error ()) throw std::runtime_error (" Error getting double" );
92- t.[:mem:] = double_result.value ();
93+ int64_t val;
94+ if (auto err = it.get (val); err) { return err; }
95+ t.[:mem:] = static_cast <int >(val);
9396 } else if constexpr (std::is_same_v<MemberType, std::string>) {
94- auto string_result = it.get_string ();
95- if (string_result.error ()) throw std::runtime_error (" Error getting string" );
96- t.[:mem:] = std::string (string_result.value ());
97- } else if constexpr (std::is_same_v<MemberType, bool >) {
98- auto bool_result = it.get_bool ();
99- if (bool_result.error ()) throw std::runtime_error (" Error getting bool" );
100- t.[:mem:] = bool_result.value ();
97+ if (auto err = it.get_string (t.[:mem:]); err) { return err; }
10198 } else {
102- t.[:mem:] = it. template get <MemberType>(). value ();
99+ if ( auto err = it. get ( t.[:mem:]); err) { return err; }
103100 }
104101 };
105102 return t;
@@ -112,34 +109,33 @@ int main() {
112109 std::string json_str = R"( {"values": [1, 2, 3]})" ;
113110 ondemand::parser parser;
114111 auto doc = parser.iterate(json_str);
115-
116- auto result = doc[" values" ].get <std::vector<int >>();
117- if (result.error ()) {
118- std::cerr << " Error parsing JSON: " << result.error () << std::endl;
119- return 1 ;
112+ std::vector<int > result;
113+ if (auto err = doc[" values" ].get <std::vector<int >>().get (result); err) {
114+ std::cerr << " Error parsing JSON: " << simdjson::error_message (err) << std::endl;
115+ return EXIT_FAILURE;
120116 }
121-
122- std::vector<int > z = result.value ();
123- for (const int &x : z) {
117+ for (const int x : result) {
124118 std::cout << x << std::endl;
125119 }
126120
127- // Test for user-defined type MyStruct
128- std::string json_str3 = R"( {"id": 1, "name": "example", "values": [1, 2, 3]})" ;
121+ // ///////////
122+ // / Notice how we won't parse directly the *document* but a value inside the document.
123+ // / That's because the document is not an instance of a value in simdjson, and so the
124+ // / current patch would require a bit of extra work to make it work with both values
125+ // / and documents
126+ // ////////////
127+ std::string json_str3 = R"( {"toto":{"id": 1, "name": "example", "values": [4, 42, 43]}})" ;
129128 ondemand::parser parser3;
130129 auto doc3 = parser3.iterate(json_str3);
131130
132- auto result3 = doc3. get <MyStruct>() ;
133- if (result3. error () ) {
134- std::cerr << " Error parsing JSON: " << result3. error ( ) << std::endl;
135- return 1 ;
131+ MyStruct result3;
132+ if ( auto err = doc3[ " toto " ]. get (result3); err ) {
133+ std::cerr << " Error parsing JSON: " << simdjson::error_message (err ) << std::endl;
134+ return EXIT_FAILURE ;
136135 }
137-
138- MyStruct my_struct = result3.value ();
139- std::cout << " ID: " << my_struct.id << " , Name: " << my_struct.name << " , Values: " ;
140- for (const int &x : my_struct.values ) {
141- std::cout << x << " " ;
136+ std::cout << " ID: " << result3.id << " , Name: " << result3.name ;
137+ for (const int x : result3.values ) {
138+ std::cout << x << std::endl;
142139 }
143- std::cout << std::endl;
144- return 0 ;
140+ return EXIT_SUCCESS;
145141}
0 commit comments