Allow direct serialization of iteratables
This commit is contained in:
parent
69d4fa193f
commit
86a577748e
|
@ -590,9 +590,10 @@ void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_N
|
||||||
// define functions providing high-level JSON serialization
|
// define functions providing high-level JSON serialization
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Serializes the specified \a reflectable which has a custom type.
|
* \brief Serializes the specified \a reflectable which has a custom type or can be mapped to and object.
|
||||||
*/
|
*/
|
||||||
template <typename Type, Traits::EnableIf<IsJsonSerializable<Type>>...> RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
|
template <typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>>...>
|
||||||
|
RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
|
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
|
||||||
RAPIDJSON_NAMESPACE::Document::Object object(document.GetObject());
|
RAPIDJSON_NAMESPACE::Document::Object object(document.GetObject());
|
||||||
|
@ -614,7 +615,7 @@ RAPIDJSON_NAMESPACE::StringBuffer toJson(Type reflectable)
|
||||||
/*!
|
/*!
|
||||||
* \brief Serializes the specified \a reflectable which is an std::string.
|
* \brief Serializes the specified \a reflectable which is an std::string.
|
||||||
*/
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_same<Type, std::string>>...>
|
template <typename Type, Traits::EnableIf<std::is_same<Type, std::string>>...>
|
||||||
RAPIDJSON_NAMESPACE::StringBuffer toJson(const std::string &reflectable)
|
RAPIDJSON_NAMESPACE::StringBuffer toJson(const std::string &reflectable)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
|
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
|
||||||
|
@ -625,19 +626,29 @@ RAPIDJSON_NAMESPACE::StringBuffer toJson(const std::string &reflectable)
|
||||||
/*!
|
/*!
|
||||||
* \brief Serializes the specified \a reflectable which is a C-string.
|
* \brief Serializes the specified \a reflectable which is a C-string.
|
||||||
*/
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_same<Type, const char *>>...> RAPIDJSON_NAMESPACE::StringBuffer toJson(const char *reflectable)
|
template <typename Type, Traits::EnableIf<std::is_same<Type, const char *>>...> RAPIDJSON_NAMESPACE::StringBuffer toJson(const char *reflectable)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
|
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
|
||||||
document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable), document.GetAllocator());
|
document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable), document.GetAllocator());
|
||||||
return serializeJsonDocToString(document);
|
return serializeJsonDocToString(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Serializes the specified \a reflectable which can be mapped to an array.
|
||||||
|
*/
|
||||||
|
template <typename Type, Traits::EnableIf<IsArray<Type>>...> RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
|
||||||
|
{
|
||||||
|
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kArrayType);
|
||||||
|
push(reflectable, document, document.GetAllocator());
|
||||||
|
return serializeJsonDocToString(document);
|
||||||
|
}
|
||||||
|
|
||||||
// define functions providing high-level JSON deserialization
|
// define functions providing high-level JSON deserialization
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Deserializes the specified JSON to \tparam Type which is a custom type.
|
* \brief Deserializes the specified JSON to \tparam Type which is a custom type or can be mapped to an object.
|
||||||
*/
|
*/
|
||||||
template <typename Type, Traits::EnableIf<IsJsonSerializable<Type>>...>
|
template <typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>>...>
|
||||||
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
|
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
||||||
|
@ -657,7 +668,7 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors
|
||||||
* \brief Deserializes the specified JSON to \tparam Type which is an integer, float or boolean.
|
* \brief Deserializes the specified JSON to \tparam Type which is an integer, float or boolean.
|
||||||
*/
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>>...>
|
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>>...>
|
||||||
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors)
|
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
||||||
if (!doc.Is<Type>()) {
|
if (!doc.Is<Type>()) {
|
||||||
|
@ -673,8 +684,8 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors
|
||||||
/*!
|
/*!
|
||||||
* \brief Deserializes the specified JSON to \tparam Type which is a std::string.
|
* \brief Deserializes the specified JSON to \tparam Type which is a std::string.
|
||||||
*/
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_same<Type, std::string>>...>
|
template <typename Type, Traits::EnableIf<std::is_same<Type, std::string>>...>
|
||||||
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors)
|
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
||||||
if (!doc.IsString()) {
|
if (!doc.IsString()) {
|
||||||
|
@ -687,10 +698,37 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors
|
||||||
return doc.GetString();
|
return doc.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Deserializes the specified JSON to \tparam Type which can be mapped to an array.
|
||||||
|
*/
|
||||||
|
template <typename Type, Traits::EnableIf<IsArray<Type>>...>
|
||||||
|
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
|
||||||
|
{
|
||||||
|
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
||||||
|
if (!doc.IsArray()) {
|
||||||
|
if (errors) {
|
||||||
|
errors->reportTypeMismatch<Type>(doc.GetType());
|
||||||
|
}
|
||||||
|
return Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
Type res;
|
||||||
|
pull<Type>(res, doc.GetArray(), errors);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Deserializes the specified JSON from an null-terminated C-string to \tparam Type.
|
||||||
|
*/
|
||||||
|
template <typename Type> Type fromJson(const char *json, JsonDeserializationErrors *errors = nullptr)
|
||||||
|
{
|
||||||
|
return fromJson<Type>(json, std::strlen(json), errors);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Deserializes the specified JSON from an std::string to \tparam Type.
|
* \brief Deserializes the specified JSON from an std::string to \tparam Type.
|
||||||
*/
|
*/
|
||||||
template <typename Type> Type fromJson(const std::string &json, JsonDeserializationErrors *errors)
|
template <typename Type> Type fromJson(const std::string &json, JsonDeserializationErrors *errors = nullptr)
|
||||||
{
|
{
|
||||||
return fromJson<Type>(json.data(), json.size(), errors);
|
return fromJson<Type>(json.data(), json.size(), errors);
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,6 +279,7 @@ void JsonReflectorTests::testSerializeNestedObjects()
|
||||||
CPPUNIT_ASSERT_EQUAL(
|
CPPUNIT_ASSERT_EQUAL(
|
||||||
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}}}"s,
|
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}}}"s,
|
||||||
string(nestingObj.toJson().GetString()));
|
string(nestingObj.toJson().GetString()));
|
||||||
|
|
||||||
NestingArray nestingArray;
|
NestingArray nestingArray;
|
||||||
nestingArray.name = "nesting2";
|
nestingArray.name = "nesting2";
|
||||||
nestingArray.testObjects.emplace_back(testObj);
|
nestingArray.testObjects.emplace_back(testObj);
|
||||||
|
@ -287,6 +288,12 @@ void JsonReflectorTests::testSerializeNestedObjects()
|
||||||
CPPUNIT_ASSERT_EQUAL(
|
CPPUNIT_ASSERT_EQUAL(
|
||||||
"{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}},{\"number\":43,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}}]}"s,
|
"{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}},{\"number\":43,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}}]}"s,
|
||||||
string(nestingArray.toJson().GetString()));
|
string(nestingArray.toJson().GetString()));
|
||||||
|
|
||||||
|
vector<TestObject> nestedInVector;
|
||||||
|
nestedInVector.emplace_back(testObj);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(
|
||||||
|
"[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}}]"s,
|
||||||
|
string(JsonReflector::toJson(nestedInVector).GetString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonReflectorTests::testSerializeUniquePtr()
|
void JsonReflectorTests::testSerializeUniquePtr()
|
||||||
|
@ -419,9 +426,12 @@ void JsonReflectorTests::testDeserializeSimpleObjects()
|
||||||
*/
|
*/
|
||||||
void JsonReflectorTests::testDeserializeNestedObjects()
|
void JsonReflectorTests::testDeserializeNestedObjects()
|
||||||
{
|
{
|
||||||
|
JsonDeserializationErrors errors;
|
||||||
const NestingObject nestingObj(NestingObject::fromJson("{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,"
|
const NestingObject nestingObj(NestingObject::fromJson("{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,"
|
||||||
"\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}"));
|
"\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}",
|
||||||
|
&errors));
|
||||||
const TestObject &testObj = nestingObj.testObj;
|
const TestObject &testObj = nestingObj.testObj;
|
||||||
|
CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
|
||||||
CPPUNIT_ASSERT_EQUAL("nesting"s, nestingObj.name);
|
CPPUNIT_ASSERT_EQUAL("nesting"s, nestingObj.name);
|
||||||
CPPUNIT_ASSERT_EQUAL(42, testObj.number);
|
CPPUNIT_ASSERT_EQUAL(42, testObj.number);
|
||||||
CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
|
CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
|
||||||
|
@ -431,8 +441,10 @@ void JsonReflectorTests::testDeserializeNestedObjects()
|
||||||
|
|
||||||
const NestingArray nestingArray(NestingArray::fromJson("{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,"
|
const NestingArray nestingArray(NestingArray::fromJson("{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,"
|
||||||
"\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3."
|
"\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3."
|
||||||
"141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}"));
|
"141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}",
|
||||||
|
&errors));
|
||||||
const vector<TestObject> &testObjects = nestingArray.testObjects;
|
const vector<TestObject> &testObjects = nestingArray.testObjects;
|
||||||
|
CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
|
||||||
CPPUNIT_ASSERT_EQUAL("nesting2"s, nestingArray.name);
|
CPPUNIT_ASSERT_EQUAL("nesting2"s, nestingArray.name);
|
||||||
CPPUNIT_ASSERT_EQUAL(2_st, testObjects.size());
|
CPPUNIT_ASSERT_EQUAL(2_st, testObjects.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(42, testObjects[0].number);
|
CPPUNIT_ASSERT_EQUAL(42, testObjects[0].number);
|
||||||
|
@ -443,6 +455,15 @@ void JsonReflectorTests::testDeserializeNestedObjects()
|
||||||
CPPUNIT_ASSERT_EQUAL("test"s, testObj.text);
|
CPPUNIT_ASSERT_EQUAL("test"s, testObj.text);
|
||||||
CPPUNIT_ASSERT_EQUAL(false, testObj.boolean);
|
CPPUNIT_ASSERT_EQUAL(false, testObj.boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto nestedInVector(JsonReflector::fromJson<vector<TestObject>>(
|
||||||
|
"[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}}]",
|
||||||
|
&errors));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(1_st, nestedInVector.size());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(42, nestedInVector[0].number);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(4_st, nestedInVector[0].numbers.size());
|
||||||
|
CPPUNIT_ASSERT_EQUAL("test"s, nestedInVector[0].text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonReflectorTests::testDeserializeUniquePtr()
|
void JsonReflectorTests::testDeserializeUniquePtr()
|
||||||
|
|
Loading…
Reference in New Issue