Skip to content

Serialization framework for C++, inspired on serde-rs for Rust.

License

Notifications You must be signed in to change notification settings

GerHobbelt/serde-cpp

 
 

Repository files navigation

serde-cpp

Serialization framework for C++17, inspired by Rust serde project.

Not ready yet !! Currently in first stage of development !! Open to contributions!

Example

No macros, no duplicate description of the struct's fields, nothing else..
You only need [[serde]] attribute on the type you want serialize.

// main.cpp
#include <serde/serde_yaml.h>
#include "main_serde.h" // generated file with serialization code

struct [[serde]] Point {
  int x;
  int y;
};

int main() {
  Point point{ 10, 20 };

  // automatic serialization
  std::string serialized = serde_yaml::to_string(point).value();
  std::cout << serialized << std::endl;

  // automatic deserialization
  Point deserialized = serde_yaml::from_str<Point>("x: 10\ny: 20\n").value();
  assert(point.x == deserialized.x && point.y == deserialized.y);
}

Summary

README

Features

  • Automatic serialization of C++ data structures (std's and user's)
  • Serialization support using valid C++17 syntax only
  • NO MACROS USED
  • Serde Cpp [[attributes]]
  • Single serialization and deserialization APIs
  • Support for multiple output formats (yaml, json, toml, ...)

How we do it?

serde-cpp generates serialization code for each header or translation unit passed to the serde generator binary. serde_gen will scan the input file for types that have [[serde]] attributes applied to them and generate the serialization and deserialization code using serde-cpp's Serializer and Deserializer APIs.

For the example above, the generated serialization/deserialization code would look like this:

// main_serde.h
#include <serde/serde.h>

namespace serde {

template<>
void serialize(serde::Serializer& ser, const Point& point)
{
  ser.serialize_struct_begin();
    ser.serialize_struct_field("x", point.x);
    ser.serialize_struct_field("y", point.y);
  ser.serialize_struct_end();
}

template<>
void deserialize(serde::Deserializer& de, Point& point)
{
  de.deserialize_struct_begin();
    de.deserialize_struct_field("x", point.x);
    de.deserialize_struct_field("y", point.y);
  de.deserialize_struct_end();
}

}  // namespace serde

Then the backend implementation of the Serializer/Deserializer will resolve the data layout.

For example, the YAML Serializer is already implemented and built into the project. So the output of this example using the YAML Serializer would be the following:

# output.yml
x: 10
y: 20

In order to generate the serde file having serialization/deserialization code for your types, a CMake command is provided. Just pass the files you want to generate code for and it will output the serialization/deserialization code for them.

# CMakeLists.txt
include(serde-cpp) # serde cmake macros
serde_generate_target(example_serde
    # generate serialization/deserialization for the following listed files
    main.cpp # a header "main_serde.h" will be generated
)
add_executable(example)
target_sources(example PRIVATE
    main.cpp
)
target_link_libraries(example PRIVATE
  example_serde # get include path of generated file
  serde_yaml
  serde
)

A template example project will be added and linked here.

Overview

serde-diagram


Project Structure

serde-cpp/serde-cpp
  • external - External library dependencies
  • extras - Extra infrastructure files
  • serde-cpp - Project source code subdirectory
    • serde - Serde APIs only
    • serde_gen - Serde auto-generation binary project
    • serde_yaml - YAML implementation of Serde APIs

Roadmap

  • Serializer interface
  • Deserializer interface
  • Builtin de/serializers
    • yaml
    • json
    • toml
    • xml
  • Deserialize complex types (template types)
  • Serde for local scope and private user types
  • Builtin std types serialization
    • string, string_view
    • vector, array
    • map, unordered_map
    • set, unordered_set
    • tuple, pair
    • optional
    • variant
    • multiset, multimap
    • unordered_multiset, unordered_multimap
    • list, forward_list
    • stack, deque, queue, priority_queue
    • initializer_list
  • Test std types serialization
  • Test builtin types serialization
  • De/Serialization for incomplete simple/template types (struct/class/enum)
  • De/Serialization for specialized types
  • CMake exported function to generate serde files automatically
  • Proper parsing/emitting error return (use exceptions?)
  • Serde generation with attributes for user types
    • enum
    • struct (POD type)
    • forward-declarations
    • foreign-types
    • additional attributes (skip, skip_de, skip_ser, rename, getter, setter, flatten, skip_none, default, ...)
  • Validate serde calls (seq/map utils) at interface level before impl (protected virtual)
  • Serde Union support
  • Support non-default constructable types
  • serde test suite
    • Invalid hierarchy (map/seq/struct..)
    • User Complex types
  • serde_attr test suite
    • Simple types
    • Template types
  • serde_yaml test suite
    • full api test
  • CMake package
  • Support wchar_t and other CharT
  • Serde-cpp project sample repo (using CMake's find_package and add_subdirectory)
  • Polymorphic objects and abstract classes ([[serde::polymorphic]])

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in serde-cpp by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Serialization framework for C++, inspired on serde-rs for Rust.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 95.8%
  • CMake 3.3%
  • C 0.9%