Imporve documentation and build script
This commit is contained in:
parent
a768408493
commit
104e362762
|
@ -16,8 +16,11 @@ set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_
|
||||||
# set project name for IDEs like Qt Creator
|
# set project name for IDEs like Qt Creator
|
||||||
project(${META_PROJECT_NAME})
|
project(${META_PROJECT_NAME})
|
||||||
|
|
||||||
|
# ensure testing is enabled at this level (and not only for particular sub directories)
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
# allow bundling c++utilities
|
# allow bundling c++utilities
|
||||||
set(BUNDLED_CPP_UTILITIES_PATH OFF CACHE FILEPATH "specifies the (relative) path to the c++utilities sources for building it together with ${META_PROJECT_NAME}")
|
set(BUNDLED_CPP_UTILITIES_PATH OFF CACHE PATH "specifies the (relative) path to the c++utilities sources for building it together with ${META_PROJECT_NAME}")
|
||||||
if(NOT BUNDLED_CPP_UTILITIES_PATH)
|
if(NOT BUNDLED_CPP_UTILITIES_PATH)
|
||||||
message(STATUS "Using system c++utilities")
|
message(STATUS "Using system c++utilities")
|
||||||
elseif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${BUNDLED_CPP_UTILITIES_PATH}" OR IS_DIRECTORY "${BUNDLED_CPP_UTILITIES_PATH}")
|
elseif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${BUNDLED_CPP_UTILITIES_PATH}" OR IS_DIRECTORY "${BUNDLED_CPP_UTILITIES_PATH}")
|
||||||
|
|
33
README.md
33
README.md
|
@ -1,4 +1,4 @@
|
||||||
# reflective-rapidjson
|
# Reflective RapidJSON
|
||||||
|
|
||||||
The main goal of this project is to provide a code generator for serializing/deserializing C++ objects to/from JSON
|
The main goal of this project is to provide a code generator for serializing/deserializing C++ objects to/from JSON
|
||||||
using Clang and RapidJSON.
|
using Clang and RapidJSON.
|
||||||
|
@ -131,9 +131,34 @@ makes use of the `reflective-rapidjson`.
|
||||||
|
|
||||||
### How to build
|
### How to build
|
||||||
Install all required dependencies and ensure the CMake script finds them. It is possible to build `c++utilities`
|
Install all required dependencies and ensure the CMake script finds them. It is possible to build `c++utilities`
|
||||||
together `reflective-rapidjson` to ease the build process. The following build script makes use of this. To use
|
together with `reflective-rapidjson` to simplify the build process. The following build script makes use of this.
|
||||||
system `c++utilities`, just skip any lines with `c++utilities` in it.
|
To use system `c++utilities`, just skip any lines with "`c++utilities`" in the following examples.
|
||||||
|
|
||||||
|
Get sources, eg. using Git:
|
||||||
```
|
```
|
||||||
TODO
|
cd $SOURCES
|
||||||
|
git clone https://github.com/Martchus/cpp-utilities.git c++utilities
|
||||||
|
git clone https://github.com/Martchus/reflective-rapidjson.git
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you don't want to build the development version, just checkout the desired version tag.
|
||||||
|
|
||||||
|
Here is an example for building with CMake and GNU Make:
|
||||||
|
```
|
||||||
|
cd $BUILD_DIR
|
||||||
|
# generate Makefile
|
||||||
|
cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE:STRING=Release \
|
||||||
|
-DCMAKE_INSTALL_PREFIX:PATH="/final/install/prefix" \
|
||||||
|
-DBUNDLED_CPP_UTILITIES_PATH:PATH="$SOURCES/c++utilities" \
|
||||||
|
"$SOURCES/reflective-rapidjson"
|
||||||
|
# build library and generators
|
||||||
|
make
|
||||||
|
# run test (optional, requires CppUnit)
|
||||||
|
make check
|
||||||
|
# generates API documentation (optional, reqquires Doxygen)
|
||||||
|
make apidoc
|
||||||
|
# install header files, libraries and generator
|
||||||
|
make install DESTDIR="/temporary/install/location"
|
||||||
|
```
|
||||||
|
Add eg. `-j$(nproc)` to `make` arguments for using all cores.
|
||||||
|
|
|
@ -34,23 +34,27 @@ set(TEST_SRC_FILES
|
||||||
tests/jsongenerator.cpp
|
tests/jsongenerator.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# find c++utilities
|
# find c++utilities and link against the library
|
||||||
find_package(c++utilities 4.11.0 REQUIRED)
|
find_package(c++utilities 4.11.0 REQUIRED)
|
||||||
use_cpp_utilities()
|
use_cpp_utilities()
|
||||||
|
|
||||||
# find libclang
|
# find Clang for LibTooling; adding clangTooling should be sufficient as it pulls all transitive dependencies
|
||||||
find_package(Clang REQUIRED)
|
find_package(Clang REQUIRED)
|
||||||
list(APPEND PRIVATE_LIBRARIES clangTooling)
|
list(APPEND PRIVATE_LIBRARIES clangTooling)
|
||||||
|
|
||||||
# also add reflective_rapidjson
|
# also add reflective_rapidjson which is header-only but might pull additional include dirs for RapidJSON
|
||||||
list(APPEND PRIVATE_LIBRARIES reflective_rapidjson)
|
list(APPEND PRIVATE_LIBRARIES reflective_rapidjson)
|
||||||
|
|
||||||
# trigger code generator for tests
|
# trigger code generator because the tests already contain structs to be (de)serialized
|
||||||
include(ReflectionGenerator)
|
include(ReflectionGenerator)
|
||||||
add_reflection_generator_invocation(
|
add_reflection_generator_invocation(
|
||||||
INPUT_FILES tests/structs.h tests/cppunit.cpp
|
INPUT_FILES
|
||||||
GENERATORS json
|
tests/structs.h # used by test cases
|
||||||
OUTPUT_LISTS TEST_HEADER_FILES
|
tests/cppunit.cpp # just for testing multiple input files and the "empty file" case
|
||||||
|
GENERATORS
|
||||||
|
json
|
||||||
|
OUTPUT_LISTS
|
||||||
|
TEST_HEADER_FILES
|
||||||
)
|
)
|
||||||
|
|
||||||
# include modules to apply configuration
|
# include modules to apply configuration
|
||||||
|
|
|
@ -26,9 +26,20 @@ set(DOC_FILES
|
||||||
README.md
|
README.md
|
||||||
)
|
)
|
||||||
|
|
||||||
# find c++utilities
|
# find c++utilities, but only add the include dirs because we're not depending on the actual library
|
||||||
find_package(c++utilities 4.11.0 REQUIRED)
|
find_package(c++utilities 4.11.0 REQUIRED)
|
||||||
use_cpp_utilities()
|
list(APPEND PUBLIC_SHARED_INCLUDE_DIRS ${CPP_UTILITIES_INCLUDE_DIRS})
|
||||||
|
list(APPEND PUBLIC_STATIC_INCLUDE_DIRS ${CPP_UTILITIES_INCLUDE_DIRS})
|
||||||
|
list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_MODULE_DIRS})
|
||||||
|
|
||||||
|
# find RapidJSON, also add only the include dirs because RapidJSON is a header-only library
|
||||||
|
find_package(RapidJSON)
|
||||||
|
if(RapidJSON_FOUND)
|
||||||
|
list(APPEND PUBLIC_SHARED_INCLUDE_DIRS ${RAPIDJSON_INCLUDE_DIRS})
|
||||||
|
list(APPEND PUBLIC_STATIC_INCLUDE_DIRS ${RAPIDJSON_INCLUDE_DIRS})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unable to find RapidJSON. Since this is the only reflection application supported at this time it makes no sense to continue.")
|
||||||
|
endif()
|
||||||
|
|
||||||
# include modules to apply configuration
|
# include modules to apply configuration
|
||||||
include(BasicConfig)
|
include(BasicConfig)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <rapidjson/rapidjson.h>
|
#include <rapidjson/rapidjson.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -23,7 +23,10 @@ namespace ReflectiveRapidJSON {
|
||||||
|
|
||||||
template <typename Type> struct JsonSerializable;
|
template <typename Type> struct JsonSerializable;
|
||||||
|
|
||||||
inline RAPIDJSON_NAMESPACE::StringBuffer documentToString(RAPIDJSON_NAMESPACE::Document &document)
|
/*!
|
||||||
|
* \brief Serializes the specified JSON \a document.
|
||||||
|
*/
|
||||||
|
inline RAPIDJSON_NAMESPACE::StringBuffer serializeJsonDocToString(RAPIDJSON_NAMESPACE::Document &document)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::StringBuffer buffer;
|
RAPIDJSON_NAMESPACE::StringBuffer buffer;
|
||||||
RAPIDJSON_NAMESPACE::Writer<RAPIDJSON_NAMESPACE::StringBuffer> writer(buffer);
|
RAPIDJSON_NAMESPACE::Writer<RAPIDJSON_NAMESPACE::StringBuffer> writer(buffer);
|
||||||
|
@ -31,7 +34,10 @@ inline RAPIDJSON_NAMESPACE::StringBuffer documentToString(RAPIDJSON_NAMESPACE::D
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline RAPIDJSON_NAMESPACE::Document parseDocumentFromString(const char *json, std::size_t jsonSize)
|
/*!
|
||||||
|
* \brief Parses the specified JSON string.
|
||||||
|
*/
|
||||||
|
inline RAPIDJSON_NAMESPACE::Document parseJsonDocFromString(const char *json, std::size_t jsonSize)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
|
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
|
||||||
const RAPIDJSON_NAMESPACE::ParseResult parseRes = document.Parse(json, jsonSize);
|
const RAPIDJSON_NAMESPACE::ParseResult parseRes = document.Parse(json, jsonSize);
|
||||||
|
@ -45,22 +51,35 @@ namespace Reflector {
|
||||||
|
|
||||||
// define functions to "push" values to a RapidJSON array or object
|
// define functions to "push" values to a RapidJSON array or object
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the \a reflectable which has a custom type to the specified array.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
||||||
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
||||||
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
|
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the \a reflectable which has a custom type to the specified object.
|
||||||
|
* \remarks The definition of this function must be provided by the code generator or Boost.Hana.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
||||||
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
||||||
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
|
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified integer/float/boolean to the specified array.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>>...>
|
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>>...>
|
||||||
inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
{
|
{
|
||||||
value.PushBack(reflectable, allocator);
|
value.PushBack(reflectable, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified C-string to the specified array.
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
inline void push<const char *>(
|
inline void push<const char *>(
|
||||||
const char *reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
const char *reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
@ -68,13 +87,9 @@ inline void push<const char *>(
|
||||||
value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
|
value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
/*!
|
||||||
inline void push<std::string>(
|
* \brief Pushes the specified constant C-string to the specified array.
|
||||||
const std::string &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
*/
|
||||||
{
|
|
||||||
value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline void push<const char *const &>(
|
inline void push<const char *const &>(
|
||||||
const char *const &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
const char *const &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
@ -82,6 +97,19 @@ inline void push<const char *const &>(
|
||||||
value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
|
value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified std::string to the specified array.
|
||||||
|
*/
|
||||||
|
template <>
|
||||||
|
inline void push<std::string>(
|
||||||
|
const std::string &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
{
|
||||||
|
value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified iteratable (eg. std::vector, std::list) to the specified array.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
template <typename Type, Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
{
|
{
|
||||||
|
@ -94,6 +122,9 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAP
|
||||||
value.PushBack(array, allocator);
|
value.PushBack(array, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified \a reflectable which has a custom type as member to the specified object.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
||||||
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
||||||
|
@ -106,6 +137,9 @@ inline void push(
|
||||||
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), object, allocator);
|
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), object, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified integer/float/boolean as member to the specified object.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>>...>
|
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>>...>
|
||||||
inline void push(
|
inline void push(
|
||||||
Type reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
Type reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
@ -113,13 +147,9 @@ inline void push(
|
||||||
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), reflectable, allocator);
|
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), reflectable, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
/*!
|
||||||
inline void push<std::string>(const std::string &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value,
|
* \brief Pushes the specified C-string as member to the specified object.
|
||||||
RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
*/
|
||||||
{
|
|
||||||
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline void push<const char *>(
|
inline void push<const char *>(
|
||||||
const char *reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
const char *reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
@ -127,6 +157,9 @@ inline void push<const char *>(
|
||||||
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
|
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified constant C-string as member to the specified object.
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
inline void push<const char *const &>(const char *const &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value,
|
inline void push<const char *const &>(const char *const &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value,
|
||||||
RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
@ -134,6 +167,19 @@ inline void push<const char *const &>(const char *const &reflectable, const char
|
||||||
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
|
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified std::string as member to the specified object.
|
||||||
|
*/
|
||||||
|
template <>
|
||||||
|
inline void push<std::string>(const std::string &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value,
|
||||||
|
RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
{
|
||||||
|
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified iteratable without size() method as member to the specified object.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::HasSize<Type>>,
|
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::HasSize<Type>>,
|
||||||
Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
|
@ -148,6 +194,9 @@ void push(
|
||||||
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), array, allocator);
|
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), array, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the specified iteratable with size() method (eg. std::vector, std::list) as member to the specified object.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::HasSize<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::HasSize<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
void push(
|
void push(
|
||||||
|
@ -162,6 +211,9 @@ void push(
|
||||||
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), array, allocator);
|
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), array, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pushes the \a reflectable which has a custom type to the specified array.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
||||||
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
||||||
|
@ -175,18 +227,28 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAP
|
||||||
|
|
||||||
// define functions to "pull" values from a RapidJSON array or object
|
// define functions to "pull" values from a RapidJSON array or object
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the \a reflectable which has a custom type from the specified value.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
||||||
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
||||||
void pull(
|
void pull(
|
||||||
Type &reflectable, RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors);
|
Type &reflectable, RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the \a reflectable which has a custom type from the specified object.
|
||||||
|
* \remarks The definition of this function must be provided by the code generator or Boost.Hana.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
||||||
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
||||||
void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
|
void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
|
||||||
JsonDeserializationErrors *errors);
|
JsonDeserializationErrors *errors);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the \a reflectable which has a custom type from the specified value which is supposed and checked to contain an object.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
|
||||||
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
|
||||||
|
@ -201,6 +263,9 @@ void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_N
|
||||||
pull<Type>(reflectable, value.GetObject(), errors);
|
pull<Type>(reflectable, value.GetObject(), errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the integer/float/boolean from the specified value iterator which is supposed and checked to contain the right type.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>>...>
|
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>>...>
|
||||||
inline void pull(
|
inline void pull(
|
||||||
Type &reflectable, RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors)
|
Type &reflectable, RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors)
|
||||||
|
@ -215,6 +280,9 @@ inline void pull(
|
||||||
++value;
|
++value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the integer/float/boolean from the specified value which is supposed and checked to contain the right type.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>>...>
|
template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>>...>
|
||||||
inline void pull(
|
inline void pull(
|
||||||
Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
||||||
|
@ -228,6 +296,9 @@ inline void pull(
|
||||||
reflectable = value.Get<Type>();
|
reflectable = value.Get<Type>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the std::string from the specified value iterator which is supposed and checked to contain a string.
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
inline void pull<std::string>(std::string &reflectable, RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value,
|
inline void pull<std::string>(std::string &reflectable, RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value,
|
||||||
JsonDeserializationErrors *errors)
|
JsonDeserializationErrors *errors)
|
||||||
|
@ -242,6 +313,9 @@ inline void pull<std::string>(std::string &reflectable, RAPIDJSON_NAMESPACE::Gen
|
||||||
++value;
|
++value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the std::string from the specified value which is supposed and checked to contain a string.
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
inline void pull<std::string>(
|
inline void pull<std::string>(
|
||||||
std::string &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
std::string &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
||||||
|
@ -255,9 +329,15 @@ inline void pull<std::string>(
|
||||||
reflectable = value.GetString();
|
reflectable = value.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the speciified \a reflectable which is an iteratable from the specified array. The \a reflectable is cleared before.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
template <typename Type, Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
|
void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the speciified \a reflectable which is an iteratable without reserve() method from the specified value iterator which is checked to contain an array.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsReservable<Type>>,
|
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsReservable<Type>>,
|
||||||
Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
|
@ -273,6 +353,9 @@ void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<c
|
||||||
++value;
|
++value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the speciified \a reflectable which is an iteratable with reserve() method from the specified value iterator which is checked to contain an array.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::IsReservable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::IsReservable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors)
|
void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors)
|
||||||
|
@ -289,6 +372,9 @@ void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<c
|
||||||
++value;
|
++value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the speciified \a reflectable which is an iteratable without reserve() method from the specified value which is checked to contain an array.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsReservable<Type>>,
|
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsReservable<Type>>,
|
||||||
Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
|
@ -303,6 +389,9 @@ void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::
|
||||||
pull(reflectable, value.GetArray(), errors);
|
pull(reflectable, value.GetArray(), errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the speciified \a reflectable which is an iteratable with reserve() method from the specified value which is checked to contain an array.
|
||||||
|
*/
|
||||||
template <typename Type,
|
template <typename Type,
|
||||||
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::IsReservable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
Traits::EnableIf<Traits::IsIteratable<Type>, Traits::IsReservable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
||||||
|
@ -318,6 +407,9 @@ void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::
|
||||||
pull(reflectable, array, errors);
|
pull(reflectable, array, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the speciified \a reflectable which is an iteratable from the specified array. The \a reflectable is cleared before.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
template <typename Type, Traits::EnableIf<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>...>
|
||||||
void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors)
|
void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors)
|
||||||
{
|
{
|
||||||
|
@ -342,6 +434,11 @@ void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pulls the speciified member of \a reflectable which has a custom type from the specified object.
|
||||||
|
* \remarks It is checked whether the object actually contains the member. If not, the missing member is ignored. So currently all members
|
||||||
|
* are optional.
|
||||||
|
*/
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
inline void pull(Type &reflectable, const char *name, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
|
inline void pull(Type &reflectable, const char *name, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
|
||||||
JsonDeserializationErrors *errors)
|
JsonDeserializationErrors *errors)
|
||||||
|
@ -370,44 +467,59 @@ inline void pull(Type &reflectable, const char *name, const rapidjson::GenericVa
|
||||||
|
|
||||||
// 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.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_base_of<JsonSerializable<Type>, Type>>...>
|
template <typename Type, Traits::EnableIfAny<std::is_base_of<JsonSerializable<Type>, Type>>...>
|
||||||
RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
|
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());
|
||||||
push(reflectable, object, document.GetAllocator());
|
push(reflectable, object, document.GetAllocator());
|
||||||
return documentToString(document);
|
return serializeJsonDocToString(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Serializes the specified \a reflectable 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>>...>
|
||||||
RAPIDJSON_NAMESPACE::StringBuffer toJson(Type reflectable)
|
RAPIDJSON_NAMESPACE::StringBuffer toJson(Type reflectable)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kNumberType);
|
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kNumberType);
|
||||||
document.Set(reflectable, document.GetAllocator());
|
document.Set(reflectable, document.GetAllocator());
|
||||||
return documentToString(document);
|
return serializeJsonDocToString(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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::EnableIfAny<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);
|
||||||
document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), document.GetAllocator());
|
document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), document.GetAllocator());
|
||||||
return documentToString(document);
|
return serializeJsonDocToString(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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::EnableIfAny<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 documentToString(document);
|
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.
|
||||||
|
*/
|
||||||
template <typename Type, Traits::EnableIfAny<std::is_base_of<JsonSerializable<Type>, Type>>...>
|
template <typename Type, Traits::EnableIfAny<std::is_base_of<JsonSerializable<Type>, 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(parseDocumentFromString(json, jsonSize));
|
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
||||||
if (!doc.IsObject()) {
|
if (!doc.IsObject()) {
|
||||||
if (errors) {
|
if (errors) {
|
||||||
errors->reportTypeMismatch<Type>(doc.GetType());
|
errors->reportTypeMismatch<Type>(doc.GetType());
|
||||||
|
@ -420,10 +532,13 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document doc(parseDocumentFromString(json, jsonSize));
|
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
||||||
if (!doc.Is<Type>()) {
|
if (!doc.Is<Type>()) {
|
||||||
if (errors) {
|
if (errors) {
|
||||||
errors->reportTypeMismatch<Type>(doc.GetType());
|
errors->reportTypeMismatch<Type>(doc.GetType());
|
||||||
|
@ -434,10 +549,13 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors
|
||||||
return doc.Get<Type>();
|
return doc.Get<Type>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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::EnableIfAny<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)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NAMESPACE::Document doc(parseDocumentFromString(json, jsonSize));
|
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
||||||
if (!doc.IsString()) {
|
if (!doc.IsString()) {
|
||||||
if (errors) {
|
if (errors) {
|
||||||
errors->reportTypeMismatch<Type>(doc.GetType());
|
errors->reportTypeMismatch<Type>(doc.GetType());
|
||||||
|
@ -448,6 +566,9 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors
|
||||||
return doc.GetString();
|
return doc.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Deserializes the specified JSON from an std::string to \tparam Type.
|
||||||
|
*/
|
||||||
template <typename Type> Type fromJson(const std::string &json)
|
template <typename Type> Type fromJson(const std::string &json)
|
||||||
{
|
{
|
||||||
return fromJson<Type>(json.data(), json.size());
|
return fromJson<Type>(json.data(), json.size());
|
||||||
|
|
|
@ -31,11 +31,6 @@ using namespace ReflectiveRapidJSON;
|
||||||
|
|
||||||
// define some structs for testing serialization
|
// define some structs for testing serialization
|
||||||
struct TestObjectHana : public JsonSerializable<TestObjectHana> {
|
struct TestObjectHana : public JsonSerializable<TestObjectHana> {
|
||||||
//TestObjectHana(){};
|
|
||||||
//TestObjectHana(const TestObjectHana &)
|
|
||||||
//{
|
|
||||||
// std::cout << "copied!!" << std::endl;
|
|
||||||
//};
|
|
||||||
BOOST_HANA_DEFINE_STRUCT(TestObjectHana, (int, number), (double, number2), (vector<int>, numbers), (string, text), (bool, boolean));
|
BOOST_HANA_DEFINE_STRUCT(TestObjectHana, (int, number), (double, number2), (vector<int>, numbers), (string, text), (bool, boolean));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,15 +45,13 @@ struct NestingArrayHana : public JsonSerializable<NestingArrayHana> {
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The ReflectorTests class tests RapidJSON wrapper which is used to ease code generation.
|
* \brief The JsonReflectorBoostHanaTests class tests the integration of Boost.Hana with the RapidJSON wrapper.
|
||||||
* \remarks In this tests, no reflection or code generation is involved yet.
|
* \remarks In these tests, the reflection is provided through Boost.Hana so the code generator is not involved.
|
||||||
*/
|
*/
|
||||||
class JSONReflectorBoostHanaTests : public TestFixture {
|
class JsonReflectorBoostHanaTests : public TestFixture {
|
||||||
CPPUNIT_TEST_SUITE(JSONReflectorBoostHanaTests);
|
CPPUNIT_TEST_SUITE(JsonReflectorBoostHanaTests);
|
||||||
CPPUNIT_TEST(testSerializePrimitives);
|
|
||||||
CPPUNIT_TEST(testSerializeSimpleObjects);
|
CPPUNIT_TEST(testSerializeSimpleObjects);
|
||||||
CPPUNIT_TEST(testSerializeNestedObjects);
|
CPPUNIT_TEST(testSerializeNestedObjects);
|
||||||
CPPUNIT_TEST(testDeserializePrimitives);
|
|
||||||
CPPUNIT_TEST(testDeserializeSimpleObjects);
|
CPPUNIT_TEST(testDeserializeSimpleObjects);
|
||||||
CPPUNIT_TEST(testDeserializeNestedObjects);
|
CPPUNIT_TEST(testDeserializeNestedObjects);
|
||||||
CPPUNIT_TEST(testHandlingTypeMismatch);
|
CPPUNIT_TEST(testHandlingTypeMismatch);
|
||||||
|
@ -79,51 +72,20 @@ public:
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(JSONReflectorBoostHanaTests);
|
CPPUNIT_TEST_SUITE_REGISTRATION(JsonReflectorBoostHanaTests);
|
||||||
|
|
||||||
void JSONReflectorBoostHanaTests::setUp()
|
void JsonReflectorBoostHanaTests::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void JSONReflectorBoostHanaTests::tearDown()
|
void JsonReflectorBoostHanaTests::tearDown()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Tests serializing strings, numbers, arrays and boolean.
|
|
||||||
*/
|
|
||||||
void JSONReflectorBoostHanaTests::testSerializePrimitives()
|
|
||||||
{
|
|
||||||
Document doc(kArrayType);
|
|
||||||
Document::AllocatorType &alloc = doc.GetAllocator();
|
|
||||||
doc.SetArray();
|
|
||||||
Document::Array array(doc.GetArray());
|
|
||||||
|
|
||||||
// string
|
|
||||||
Reflector::push<string>("foo"s, array, alloc);
|
|
||||||
Reflector::push<const char *>("bar", array, alloc);
|
|
||||||
// number
|
|
||||||
Reflector::push<int>(25, array, alloc);
|
|
||||||
Reflector::push<double>(12.5, array, alloc);
|
|
||||||
// array
|
|
||||||
Reflector::push<vector<const char *>>({ "foo1", "bar1" }, array, alloc);
|
|
||||||
Reflector::push<list<const char *>>({ "foo2", "bar2" }, array, alloc);
|
|
||||||
Reflector::push<initializer_list<const char *>>({ "foo3", "bar3" }, array, alloc);
|
|
||||||
// boolean
|
|
||||||
Reflector::push<bool>(true, array, alloc);
|
|
||||||
Reflector::push<bool>(false, array, alloc);
|
|
||||||
|
|
||||||
StringBuffer strbuf;
|
|
||||||
Writer<StringBuffer> jsonWriter(strbuf);
|
|
||||||
doc.Accept(jsonWriter);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(
|
|
||||||
"[\"foo\",\"bar\",25,12.5,[\"foo1\",\"bar1\"],[\"foo2\",\"bar2\"],[\"foo3\",\"bar3\"],true,false]"s, string(strbuf.GetString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests serializing objects.
|
* \brief Tests serializing objects.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorBoostHanaTests::testSerializeSimpleObjects()
|
void JsonReflectorBoostHanaTests::testSerializeSimpleObjects()
|
||||||
{
|
{
|
||||||
TestObjectHana testObj;
|
TestObjectHana testObj;
|
||||||
testObj.number = 42;
|
testObj.number = 42;
|
||||||
|
@ -138,7 +100,7 @@ void JSONReflectorBoostHanaTests::testSerializeSimpleObjects()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests serializing nested object and arrays.
|
* \brief Tests serializing nested object and arrays.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorBoostHanaTests::testSerializeNestedObjects()
|
void JsonReflectorBoostHanaTests::testSerializeNestedObjects()
|
||||||
{
|
{
|
||||||
NestingObjectHana nestingObj;
|
NestingObjectHana nestingObj;
|
||||||
nestingObj.name = "nesting";
|
nestingObj.name = "nesting";
|
||||||
|
@ -161,43 +123,10 @@ void JSONReflectorBoostHanaTests::testSerializeNestedObjects()
|
||||||
string(nestingArray.toJson().GetString()));
|
string(nestingArray.toJson().GetString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Tests deserializing strings, numbers (int, float, double) and boolean.
|
|
||||||
*/
|
|
||||||
void JSONReflectorBoostHanaTests::testDeserializePrimitives()
|
|
||||||
{
|
|
||||||
Document doc(kArrayType);
|
|
||||||
|
|
||||||
doc.Parse("[\"a\", 5, 5e6, \"test\", true, 4.125, false]");
|
|
||||||
auto array = doc.GetArray().begin();
|
|
||||||
|
|
||||||
string str1, str2;
|
|
||||||
int int1 = 0;
|
|
||||||
bool bool1 = false, bool2 = true;
|
|
||||||
float float1 = 0.0;
|
|
||||||
double double1 = 0.0;
|
|
||||||
JsonDeserializationErrors errors;
|
|
||||||
Reflector::pull(str1, array, &errors);
|
|
||||||
Reflector::pull(int1, array, &errors);
|
|
||||||
Reflector::pull(float1, array, &errors);
|
|
||||||
Reflector::pull(str2, array, &errors);
|
|
||||||
Reflector::pull(bool1, array, &errors);
|
|
||||||
Reflector::pull(double1, array, &errors);
|
|
||||||
Reflector::pull(bool2, array, &errors);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL("a"s, str1);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(5, int1);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(5e6f, float1);
|
|
||||||
CPPUNIT_ASSERT_EQUAL("test"s, str2);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(true, bool1);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(4.125, double1);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(false, bool2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests deserializing simple objects.
|
* \brief Tests deserializing simple objects.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorBoostHanaTests::testDeserializeSimpleObjects()
|
void JsonReflectorBoostHanaTests::testDeserializeSimpleObjects()
|
||||||
{
|
{
|
||||||
const TestObjectHana testObj(
|
const TestObjectHana testObj(
|
||||||
TestObjectHana::fromJson("{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}"));
|
TestObjectHana::fromJson("{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}"));
|
||||||
|
@ -212,7 +141,7 @@ void JSONReflectorBoostHanaTests::testDeserializeSimpleObjects()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests deserializing nested objects and arrays.
|
* \brief Tests deserializing nested objects and arrays.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorBoostHanaTests::testDeserializeNestedObjects()
|
void JsonReflectorBoostHanaTests::testDeserializeNestedObjects()
|
||||||
{
|
{
|
||||||
const NestingObjectHana nestingObj(NestingObjectHana::fromJson("{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,"
|
const NestingObjectHana nestingObj(NestingObjectHana::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}}"));
|
||||||
|
@ -244,7 +173,7 @@ void JSONReflectorBoostHanaTests::testDeserializeNestedObjects()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests whether JsonDeserializationError is thrown on type mismatch.
|
* \brief Tests whether JsonDeserializationError is thrown on type mismatch.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorBoostHanaTests::testHandlingTypeMismatch()
|
void JsonReflectorBoostHanaTests::testHandlingTypeMismatch()
|
||||||
{
|
{
|
||||||
JsonDeserializationErrors errors;
|
JsonDeserializationErrors errors;
|
||||||
NestingArrayHana::fromJson("{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,"
|
NestingArrayHana::fromJson("{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,"
|
||||||
|
|
|
@ -129,11 +129,11 @@ inline void pull<NestingArray>(NestingArray &reflectable, const GenericValue<UTF
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The ReflectorTests class tests RapidJSON wrapper which is used to ease code generation.
|
* \brief The JsonReflectorTests class tests RapidJSON wrapper which is used to ease code generation.
|
||||||
* \remarks In this tests, no reflection or code generation is involved yet.
|
* \remarks In these tests, the required reflection code is provided by hand so the generator isn't involved yet.
|
||||||
*/
|
*/
|
||||||
class JSONReflectorTests : public TestFixture {
|
class JsonReflectorTests : public TestFixture {
|
||||||
CPPUNIT_TEST_SUITE(JSONReflectorTests);
|
CPPUNIT_TEST_SUITE(JsonReflectorTests);
|
||||||
CPPUNIT_TEST(testSerializePrimitives);
|
CPPUNIT_TEST(testSerializePrimitives);
|
||||||
CPPUNIT_TEST(testSerializeSimpleObjects);
|
CPPUNIT_TEST(testSerializeSimpleObjects);
|
||||||
CPPUNIT_TEST(testSerializeNestedObjects);
|
CPPUNIT_TEST(testSerializeNestedObjects);
|
||||||
|
@ -161,20 +161,20 @@ public:
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(JSONReflectorTests);
|
CPPUNIT_TEST_SUITE_REGISTRATION(JsonReflectorTests);
|
||||||
|
|
||||||
void JSONReflectorTests::setUp()
|
void JsonReflectorTests::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void JSONReflectorTests::tearDown()
|
void JsonReflectorTests::tearDown()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests serializing strings, numbers, arrays and boolean.
|
* \brief Tests serializing strings, numbers, arrays and boolean.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorTests::testSerializePrimitives()
|
void JsonReflectorTests::testSerializePrimitives()
|
||||||
{
|
{
|
||||||
Document doc(kArrayType);
|
Document doc(kArrayType);
|
||||||
Document::AllocatorType &alloc = doc.GetAllocator();
|
Document::AllocatorType &alloc = doc.GetAllocator();
|
||||||
|
@ -205,7 +205,7 @@ void JSONReflectorTests::testSerializePrimitives()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests serializing objects.
|
* \brief Tests serializing objects.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorTests::testSerializeSimpleObjects()
|
void JsonReflectorTests::testSerializeSimpleObjects()
|
||||||
{
|
{
|
||||||
TestObject testObj;
|
TestObject testObj;
|
||||||
testObj.number = 42;
|
testObj.number = 42;
|
||||||
|
@ -220,7 +220,7 @@ void JSONReflectorTests::testSerializeSimpleObjects()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests serializing nested object and arrays.
|
* \brief Tests serializing nested object and arrays.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorTests::testSerializeNestedObjects()
|
void JsonReflectorTests::testSerializeNestedObjects()
|
||||||
{
|
{
|
||||||
NestingObject nestingObj;
|
NestingObject nestingObj;
|
||||||
nestingObj.name = "nesting";
|
nestingObj.name = "nesting";
|
||||||
|
@ -246,7 +246,7 @@ void JSONReflectorTests::testSerializeNestedObjects()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests deserializing strings, numbers (int, float, double) and boolean.
|
* \brief Tests deserializing strings, numbers (int, float, double) and boolean.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorTests::testDeserializePrimitives()
|
void JsonReflectorTests::testDeserializePrimitives()
|
||||||
{
|
{
|
||||||
Document doc(kArrayType);
|
Document doc(kArrayType);
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ void JSONReflectorTests::testDeserializePrimitives()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests deserializing simple objects.
|
* \brief Tests deserializing simple objects.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorTests::testDeserializeSimpleObjects()
|
void JsonReflectorTests::testDeserializeSimpleObjects()
|
||||||
{
|
{
|
||||||
const TestObject testObj(
|
const TestObject testObj(
|
||||||
TestObject::fromJson("{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}"));
|
TestObject::fromJson("{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}"));
|
||||||
|
@ -294,7 +294,7 @@ void JSONReflectorTests::testDeserializeSimpleObjects()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests deserializing nested objects and arrays.
|
* \brief Tests deserializing nested objects and arrays.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorTests::testDeserializeNestedObjects()
|
void JsonReflectorTests::testDeserializeNestedObjects()
|
||||||
{
|
{
|
||||||
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}}"));
|
||||||
|
@ -325,7 +325,7 @@ void JSONReflectorTests::testDeserializeNestedObjects()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests whether RAPIDJSON_NAMESPACE::ParseResult is thrown correctly when passing invalid JSON to fromJSON().
|
* \brief Tests whether RAPIDJSON_NAMESPACE::ParseResult is thrown correctly when passing invalid JSON to fromJSON().
|
||||||
*/
|
*/
|
||||||
void JSONReflectorTests::testHandlingParseError()
|
void JsonReflectorTests::testHandlingParseError()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
NestingObject::fromJson("{\"name\":nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":"
|
NestingObject::fromJson("{\"name\":nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":"
|
||||||
|
@ -340,7 +340,7 @@ void JSONReflectorTests::testHandlingParseError()
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests whether JsonDeserializationError is thrown on type mismatch.
|
* \brief Tests whether JsonDeserializationError is thrown on type mismatch.
|
||||||
*/
|
*/
|
||||||
void JSONReflectorTests::testHandlingTypeMismatch()
|
void JsonReflectorTests::testHandlingTypeMismatch()
|
||||||
{
|
{
|
||||||
JsonDeserializationErrors errors;
|
JsonDeserializationErrors errors;
|
||||||
NestingArray::fromJson("{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,"
|
NestingArray::fromJson("{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,"
|
||||||
|
|
Loading…
Reference in New Issue