From 067a07b25e6ba0bd8eb39a592b50cabaf5b9e836 Mon Sep 17 00:00:00 2001 From: David Yackzan Date: Tue, 28 Jan 2025 17:47:20 -0700 Subject: [PATCH] Add type & value fields to primitive json types This aligns with how custom types are represented by the JsonExporter. * Update both toJson & fromJson functions in the JsonExporter * Add & update tests --- src/json_export.cpp | 61 ++++++++++++++++++++++++++------------------ tests/gtest_json.cpp | 23 ++++++++++++++--- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/json_export.cpp b/src/json_export.cpp index 1baac478a..1c738b194 100644 --- a/src/json_export.cpp +++ b/src/json_export.cpp @@ -14,21 +14,28 @@ bool JsonExporter::toJson(const Any& any, nlohmann::json& dst) const nlohmann::json json; auto const& type = any.castedType(); + const std::string type_field = "__type"; + const std::string value_field = "value"; + if(any.isString()) { - dst = any.cast(); + dst[type_field] = "string"; + dst[value_field] = any.cast(); } else if(type == typeid(int64_t)) { - dst = any.cast(); + dst[type_field] = "int64_t"; + dst[value_field] = any.cast(); } else if(type == typeid(uint64_t)) { - dst = any.cast(); + dst[type_field] = "uint64_t"; + dst[value_field] = any.cast(); } else if(type == typeid(double)) { - dst = any.cast(); + dst[type_field] = "double"; + dst[value_field] = any.cast(); } else { @@ -51,32 +58,36 @@ JsonExporter::ExpectedEntry JsonExporter::fromJson(const nlohmann::json& source) { return nonstd::make_unexpected("json object is null"); } - if(source.is_string()) - { - return Entry{ BT::Any(source.get()), - BT::TypeInfo::Create() }; - } - if(source.is_number_unsigned()) - { - return Entry{ BT::Any(source.get()), BT::TypeInfo::Create() }; - } - if(source.is_number_integer()) - { - return Entry{ BT::Any(source.get()), BT::TypeInfo::Create() }; - } - if(source.is_number_float()) - { - return Entry{ BT::Any(source.get()), BT::TypeInfo::Create() }; - } - if(source.is_boolean()) + if(!source.contains("__type")) { - return Entry{ BT::Any(source.get()), BT::TypeInfo::Create() }; + return nonstd::make_unexpected("Missing field '__type'"); } - if(!source.contains("__type")) + if (source.contains("value")) { - return nonstd::make_unexpected("Missing field '__type'"); + if(source["value"].is_string()) + { + return Entry{ BT::Any(source["value"].get()), + BT::TypeInfo::Create() }; + } + if(source["value"].is_number_unsigned()) + { + return Entry{ BT::Any(source["value"].get()), BT::TypeInfo::Create() }; + } + if(source["value"].is_number_integer()) + { + return Entry{ BT::Any(source["value"].get()), BT::TypeInfo::Create() }; + } + if(source["value"].is_number_float()) + { + return Entry{ BT::Any(source["value"].get()), BT::TypeInfo::Create() }; + } + if(source["value"].is_boolean()) + { + return Entry{ BT::Any(source["value"].get()), BT::TypeInfo::Create() }; + } } + auto type_it = type_names_.find(source["__type"]); if(type_it == type_names_.end()) { diff --git a/tests/gtest_json.cpp b/tests/gtest_json.cpp index f7b9e5909..89f98dffc 100644 --- a/tests/gtest_json.cpp +++ b/tests/gtest_json.cpp @@ -95,14 +95,25 @@ TEST_F(JsonTest, TwoWaysConversion) TestTypes::Pose3D pose = { { 1, 2, 3 }, { 4, 5, 6, 7 } }; nlohmann::json json; + exporter.toJson(BT::Any("string_val"), json["string"]); exporter.toJson(BT::Any(69), json["int"]); + exporter.toJson(BT::Any(static_cast(96)), json["uint"]); exporter.toJson(BT::Any(3.14), json["real"]); exporter.toJson(BT::Any(pose), json["pose"]); std::cout << json.dump(2) << std::endl; - ASSERT_EQ(json["int"], 69); - ASSERT_EQ(json["real"], 3.14); + ASSERT_EQ(json["string"]["__type"], "string"); + ASSERT_EQ(json["string"]["value"], "string_val"); + + ASSERT_EQ(json["int"]["__type"], "int64_t"); + ASSERT_EQ(json["int"]["value"], 69); + + ASSERT_EQ(json["uint"]["__type"], "uint64_t"); + ASSERT_EQ(json["uint"]["value"], 96); + + ASSERT_EQ(json["real"]["__type"], "double"); + ASSERT_EQ(json["real"]["value"], 3.14); ASSERT_EQ(json["pose"]["__type"], "Pose3D"); ASSERT_EQ(json["pose"]["pos"]["x"], 1); @@ -126,8 +137,12 @@ TEST_F(JsonTest, TwoWaysConversion) ASSERT_EQ(pose.rot.y, pose2.rot.y); ASSERT_EQ(pose.rot.z, pose2.rot.z); - auto num = exporter.fromJson(json["int"])->first.cast(); - ASSERT_EQ(num, 69); + auto string_val = exporter.fromJson(json["string"])->first.cast(); + ASSERT_EQ(string_val, "string_val"); + auto int_val = exporter.fromJson(json["int"])->first.cast(); + ASSERT_EQ(int_val, 69); + auto uint_val = exporter.fromJson(json["uint"])->first.cast(); + ASSERT_EQ(uint_val, 96); auto real = exporter.fromJson(json["real"])->first.cast(); ASSERT_EQ(real, 3.14); }