Code generator for serializing/deserializing C++ objects to/from JSON using Clang and RapidJSON
Go to file
Martchus 2933a3a29a WIP: Add toJsonAs() 2017-10-27 15:36:09 +02:00
generator WIP: Add toJsonAs() 2017-10-27 15:36:09 +02:00
lib WIP: Add toJsonAs() 2017-10-27 15:36:09 +02:00
.gitignore Add project basic project structure 2017-10-19 01:10:51 +02:00
CMakeLists.txt Rename moc -> generator 2017-10-25 17:41:19 +02:00
LICENSE Add project basic project structure 2017-10-19 01:10:51 +02:00
README.md Extend README.md 2017-10-25 20:08:22 +02:00

README.md

reflective-rapidjson

The main goal of this project is to provide a code generator for serializing/deserializing C++ objects to/from JSON using Clang and RapidJSON.

However, extending the generator to generate code for other applications of reflection or to provide generic reflection functionallity would be possible as well.

This repository also contains a small, additional header to use RapidJSON with Boost.Hana. This allows to serialize or dezerialize simple data structures using the BOOST_HANA_DEFINE_STRUCT macro rather than requiring the code generator.

Usage

This example shows how the library can be used to make a struct serializable:

#include "<reflective-rapidjson/jsonserializable.h>

// define structures, eg.
struct TestObject : public JSONSerializable<TestObject> {
    int number;
    double number2;
    vector<int> numbers;
    string text;
    bool boolean;
};
struct NestingObject : public JSONSerializable<NestingObject> {
    string name;
    TestObject testObj;
};
struct NestingArray : public JSONSerializable<NestingArray> {
    string name;
    vector<TestObject> testObjects;
};

// serialize to JSON
NestingArray obj{ ... };
cout << "JSON: " << obj.toJson().GetString();

// deserialize from JSON
const auto obj = NestingArray::fromJson(...);

// in exactly one of the project's translation units
#include "reflection/code-defining-structs.h"

Note that the header included at the bottom must be generated by invoking the code generator appropriately, eg.:

reflective_rapidjson_generator -i "$srcdir/code-defining-structs.cpp" -o "$builddir/reflection/code-defining-structs.h"

It is possible to use the provided CMake macro to automate this task:

find_package(reflective-rapidjson REQUIRED)
list(APPEND CMAKE_MODULE_PATH ${REFLECTIVE_RAPIDJSON_MODULE_DIRS})
include(ReflectionGenerator)

add_reflection_generator_invocation(
    INPUT_FILES code-defining-structs.cpp
    GENERATORS json
    OUTPUT_LISTS LIST_OF_GENERATED_HEADERS
)

This will produce the file code-defining-structs.h in the directory reflection in the current build directory. So make sure the current build directory is added to the include directories of your target. The default output directory can also be overridden by passing OUTPUT_DIRECTORY custom/directory to the arguments.

It is possible to specify multiple input files at once. A separate output file is generated for each input. The output files will always have the extension ".h", independently of the extension of the input file.

The full paths of the generated files are also appended to the variable LIST_OF_GENERATED_HEADERS which then can be added to the sources of your target. Of course this can be skipped if not required/wanted.

Using Boost.Hana instead of the code generator

The same example as above. However, this time Boost.Hana is used - so it doesn't require invoking the generator.

#include "<reflective-rapidjson/jsonserializable-boosthana.h>

// define structures using BOOST_HANA_DEFINE_STRUCT, eg.
struct TestObject : public JSONSerializable<TestObject> {
    BOOST_HANA_DEFINE_STRUCT(TestObject,
        (int, number),
        (double, number2),
        (vector<int>, numbers),
        (string, text),
        (bool, boolean)
    );
};
struct NestingObject : public JSONSerializable<NestingObject> {
    BOOST_HANA_DEFINE_STRUCT(NestingObject,
        (string, name),
        (TestObject, testObj)
    );
};
struct NestingArray : public JSONSerializable<NestingArray> {
    BOOST_HANA_DEFINE_STRUCT(NestingArray,
        (string, name),
        (vector<TestObject>, testObjects)
    );
};

// serialize to JSON
NestingArray obj{ ... };
cout << "JSON: " << obj.toJson().GetString();

// deserialize from JSON
const auto obj = NestingArray::fromJson(...);

So the usage remains the same.

Install instructions

Dependencies

  • C++ compiler and standard library supporting at least C++14
  • the CMake build system
  • LibTooling from Clang for the code generator
  • RapidJSON for JSON (de)serialization
  • Boost.Hana for using BOOST_HANA_DEFINE_STRUCT instead of code generator
  • c++utilities for various helper functions

Optional:

  • CppUnit for building and running the tests
  • Doxygen for generating API documentation
  • Graphviz for diagrams in the API documentation

Note that reflective-rapidjson and none of these dependencies are required at runtime by an application which makes use of the reflective-rapidjson.

How to build

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 system c++utilities, just skip any lines with c++utilities in it.

TODO