#include "simdjson.h" #include "test_builder.h" #include #include #include using namespace simdjson; struct kid { int age; std::string name; std::vector toys; auto operator<=>(const kid &) const = default; }; //////////////////// // We do it manually, but this should be done by static reflection: //////////////////// namespace simdjson { // This tag_invoke MUST be inside simdjson namespace template auto tag_invoke(deserialize_tag, simdjson_value &val, kid &k) { ondemand::object obj; auto error = val.get_object().get(obj); if (error) { return error; } if ((error = obj["age"].get(k.age))) { return error; } if ((error = obj["name"].get_string(k.name))) { return error; } std::vector toys; // annoying we cannot do get>(k.toys)!!! if ((error = obj["toys"].get>().get(toys))) { return error; } for (auto toy : toys) { k.toys.push_back(std::string(toy)); } return simdjson::SUCCESS; } } // namespace simdjson struct Z { int x; }; struct Y { int g; std::string h; std::vector i; Z z; }; struct X { char a; int b; int c; std::string d; std::vector e; std::vector f; Y y; }; namespace builder_tests { bool serialize_deserialize_kid() { TEST_START(); simdjson::padded_string json_str = R"({"age": 12, "name": "John", "toys": ["car", "ball"]})"_padded; simdjson::ondemand::parser parser; simdjson::ondemand::document doc; ASSERT_SUCCESS(parser.iterate(json_str).get(doc)); kid k; ASSERT_SUCCESS(doc.get().get(k)); ASSERT_EQUAL(k.age, 12); ASSERT_EQUAL(k.name, "John"); ASSERT_EQUAL(k.toys.size(), 2); ASSERT_EQUAL(k.toys[0], "car"); ASSERT_EQUAL(k.toys[1], "ball"); // Now, go the other direction: std::string json; ASSERT_SUCCESS(simdjson::builder::to_json_string(k).get(json)); std::cout << json << std::endl; // Now we parse it back: simdjson::ondemand::parser parser2; simdjson::ondemand::document doc2; ASSERT_SUCCESS(parser2.iterate(simdjson::pad(json)).get(doc2)); kid k2; ASSERT_SUCCESS(doc2.get().get(k2)); ASSERT_EQUAL(k2.age, 12); ASSERT_EQUAL(k2.name, "John"); ASSERT_EQUAL(k2.toys.size(), 2); ASSERT_EQUAL(k2.toys[0], "car"); ASSERT_EQUAL(k2.toys[1], "ball"); TEST_SUCCEED(); } bool serialize_deserialize_x_y_z() { TEST_START(); X s1 = {.a = '1', .b = 10, .c = 0, .d = "test string\n\r\"", .e = {1, 2, 3}, .f = {"ab", "cd", "fg"}, .y = {.g = 100, .h = "test string\n\r\"", .i = {1, 2, 3}, .z = {.x = 1000}}}; std::string json_str; simdjson::builder::string_builder sb; fast_to_json_string(sb, s1); std::string_view p; ASSERT_SUCCESS(sb.view().get(p)); std::string pstr(p.data(), p.size()); std::cout << p << std::endl; ASSERT_EQUAL( pstr, R"({"a":1,"b":10,"c":0,"d":"test string\n\r\"","e":[1,2,3],"f":["ab","cd","fg"],"y":{"g":100,"h":"test string\n\r\"","i":[1,2,3],"z":{"x":1000}}})"); TEST_SUCCEED(); } bool run() { return serialize_deserialize_kid() && serialize_deserialize_x_y_z() && true; } } // namespace builder_tests int main(int argc, char *argv[]) { return test_main(argc, argv, builder_tests::run); }