Skip to content

Commit

Permalink
Merge branch 'main' into f/fix_yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzicheng1987 committed Dec 22, 2024
2 parents 37a0be8 + 23ce24f commit e1a47ed
Show file tree
Hide file tree
Showing 118 changed files with 4,818 additions and 272 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
**/build_clang/**

# Output files
*.avro
*.bson
*.cbor
*.json
Expand Down
20 changes: 19 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.23)
option(REFLECTCPP_BUILD_SHARED "Build shared library" ${BUILD_SHARED_LIBS})

option(REFLECTCPP_JSON "Enable JSON support" ON) # enabled by default
option(REFLECTCPP_AVRO "Enable AVRO support" OFF)
option(REFLECTCPP_BSON "Enable BSON support" OFF)
option(REFLECTCPP_CBOR "Enable CBOR support" OFF)
option(REFLECTCPP_FLEXBUFFERS "Enable flexbuffers support" OFF)
Expand All @@ -21,6 +22,7 @@ set(REFLECTCPP_USE_VCPKG_DEFAULT OFF)

if(REFLECTCPP_BUILD_BENCHMARKS)
set(REFLECTCPP_JSON ON CACHE BOOL "" FORCE)
set(REFLECTCPP_AVRO ON CACHE BOOL "" FORCE)
set(REFLECTCPP_BSON ON CACHE BOOL "" FORCE)
set(REFLECTCPP_CBOR ON CACHE BOOL "" FORCE)
set(REFLECTCPP_FLEXBUFFERS ON CACHE BOOL "" FORCE)
Expand All @@ -32,7 +34,7 @@ if(REFLECTCPP_BUILD_BENCHMARKS)
endif()

if (REFLECTCPP_BUILD_TESTS OR REFLECTCPP_BUILD_BENCHMARKS OR
(REFLECTCPP_JSON AND NOT REFLECTCPP_USE_BUNDLED_DEPENDENCIES) OR
(REFLECTCPP_JSON AND NOT REFLECTCPP_USE_BUNDLED_DEPENDENCIES) OR REFLECTCPP_AVRO OR
REFLECTCPP_BSON OR REFLECTCPP_CBOR OR REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_MSGPACK OR REFLECTCPP_XML OR REFLECTCPP_TOML OR REFLECTCPP_UBJSON OR REFLECTCPP_YAML)
# enable vcpkg per default if require features other than JSON
set(REFLECTCPP_USE_VCPKG_DEFAULT ON)
Expand Down Expand Up @@ -101,6 +103,22 @@ if (REFLECTCPP_JSON)
endif ()
endif ()

if (REFLECTCPP_AVRO)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_avro.cpp
)
find_package(jansson CONFIG REQUIRED)
if(REFLECTCPP_USE_VCPKG)
target_include_directories(reflectcpp SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include")
if (MSVC)
target_link_libraries(reflectcpp PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/avro${CMAKE_STATIC_LIBRARY_SUFFIX}")
else ()
target_link_libraries(reflectcpp PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/libavro${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif ()
endif()
target_link_libraries(reflectcpp PRIVATE jansson::jansson)
endif ()

if (REFLECTCPP_BSON)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_bson.cpp
Expand Down
13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,7 @@
[![Generic badge](https://img.shields.io/badge/MSVC-17+-blue.svg)](https://shields.io/)
[![Conan Center](https://img.shields.io/conan/v/reflect-cpp)](https://conan.io/center/recipes/reflect-cpp)


**📖 Documentation**: https://rfl.getml.com**👨‍💻 Source Code**: https://github.com/getml/reflect-cpp

><br> **📣 From the Author (12.11.2024):** Hi everyone, Patrick ([liuzicheng1987](https://github.com/liuzicheng1987)) here. With reflect-cpp reaching the 1k-star milestone, we’re excited to roll out an overhauled documentation site at [https://rfl.getml.com](https://rfl.getml.com/), giving it a permanent place in our company. Initially developed as an internal tool for our machine learning library, [getML](https://getml.com), reflect-cpp has grown into something much larger.
<br> A big thank you to all contributors for helping us reach this point! Your feedback, ideas, and dedication have been invaluable.
<br> As we look to the project’s future, I would like to hear your thoughts on potential new directions, discuss ideas to expand our user base, or learn more about what you’re building with it. For the next month, I am opening a few slots in my calendar for anyone who wants to [connect (link)](https://calendar.app.google/AaeziooCNierbwAZ8).
<br> *— Best, Patrick*
<br>&nbsp;
**📖 Documentation**: https://rfl.getml.com

![image](banner1.png)

Expand Down Expand Up @@ -71,6 +63,7 @@ The following table lists the serialization formats currently supported by refle
| Format | Library | Version | License | Remarks |
|--------------|------------------------------------------------------|--------------|------------| -----------------------------------------------------|
| JSON | [yyjson](https://github.com/ibireme/yyjson) | >= 0.8.0 | MIT | out-of-the-box support, included in this repository |
| Avro | [avro-c](https://avro.apache.org/docs/1.11.1/api/c/) | >= 1.11.3 | Apache 2.0 | Schemaful binary format |
| BSON | [libbson](https://github.com/mongodb/mongo-c-driver) | >= 1.25.1 | Apache 2.0 | JSON-like binary format |
| CBOR | [tinycbor](https://github.com/intel/tinycbor) | >= 0.6.0 | MIT | JSON-like binary format |
| flexbuffers | [flatbuffers](https://github.com/google/flatbuffers) | >= 23.5.26 | Apache 2.0 | Schema-less version of flatbuffers, binary format |
Expand Down Expand Up @@ -153,6 +146,7 @@ This will work for just about any example in the entire documentation
and any supported format, except where explicitly noted otherwise:
```cpp
rfl::avro::write(homer);
rfl::bson::write(homer);
rfl::cbor::write(homer);
rfl::flexbuf::write(homer);
Expand All @@ -161,6 +155,7 @@ rfl::toml::write(homer);
rfl::ubjson::write(homer);
rfl::xml::write(homer);

rfl::avro::read<Person>(avro_bytes);
rfl::bson::read<Person>(bson_bytes);
rfl::cbor::read<Person>(cbor_bytes);
rfl::flexbuf::read<Person>(flexbuf_bytes);
Expand Down
13 changes: 13 additions & 0 deletions benchmarks/all/canada_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <iostream>
#include <optional>
#include <rfl/avro.hpp>
#include <rfl/bson.hpp>
#include <rfl/cbor.hpp>
#include <rfl/flexbuf.hpp>
Expand Down Expand Up @@ -47,6 +48,18 @@ static FeatureCollection load_data() {

// ----------------------------------------------------------------------------

static void BM_canada_read_reflect_cpp_avro(benchmark::State &state) {
const auto schema = rfl::avro::to_schema<FeatureCollection>();
const auto data = rfl::avro::write(load_data(), schema);
for (auto _ : state) {
const auto res = rfl::avro::read<FeatureCollection>(data, schema);
if (!res) {
std::cout << res.error()->what() << std::endl;
}
}
}
BENCHMARK(BM_canada_read_reflect_cpp_avro);

static void BM_canada_read_reflect_cpp_bson(benchmark::State &state) {
const auto data = rfl::bson::write(load_data());
for (auto _ : state) {
Expand Down
13 changes: 13 additions & 0 deletions benchmarks/all/canada_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <iostream>
#include <optional>
#include <rfl/avro.hpp>
#include <rfl/bson.hpp>
#include <rfl/cbor.hpp>
#include <rfl/flexbuf.hpp>
Expand Down Expand Up @@ -47,6 +48,18 @@ static FeatureCollection load_data() {

// ----------------------------------------------------------------------------

static void BM_canada_write_reflect_cpp_avro(benchmark::State &state) {
const auto schema = rfl::avro::to_schema<FeatureCollection>();
const auto data = load_data();
for (auto _ : state) {
const auto output = rfl::avro::write(data, schema);
if (output.size() == 0) {
std::cout << "No output" << std::endl;
}
}
}
BENCHMARK(BM_canada_write_reflect_cpp_avro);

static void BM_canada_write_reflect_cpp_bson(benchmark::State &state) {
const auto data = load_data();
for (auto _ : state) {
Expand Down
13 changes: 13 additions & 0 deletions benchmarks/all/licenses_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <iostream>
#include <optional>
#include <rfl/avro.hpp>
#include <rfl/bson.hpp>
#include <rfl/cbor.hpp>
#include <rfl/flexbuf.hpp>
Expand Down Expand Up @@ -63,6 +64,18 @@ static Licenses load_data() {

// ----------------------------------------------------------------------------

static void BM_licenses_read_reflect_cpp_avro(benchmark::State &state) {
const auto schema = rfl::avro::to_schema<Licenses>();
const auto data = rfl::avro::write(load_data(), schema);
for (auto _ : state) {
const auto res = rfl::avro::read<Licenses>(data, schema);
if (!res) {
std::cout << res.error()->what() << std::endl;
}
}
}
BENCHMARK(BM_licenses_read_reflect_cpp_avro);

static void BM_licenses_read_reflect_cpp_bson(benchmark::State &state) {
const auto data = rfl::bson::write(load_data());
for (auto _ : state) {
Expand Down
13 changes: 13 additions & 0 deletions benchmarks/all/licenses_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <iostream>
#include <optional>
#include <rfl/avro.hpp>
#include <rfl/bson.hpp>
#include <rfl/cbor.hpp>
#include <rfl/flexbuf.hpp>
Expand Down Expand Up @@ -63,6 +64,18 @@ static Licenses load_data() {

// ----------------------------------------------------------------------------

static void BM_licenses_write_reflect_cpp_avro(benchmark::State &state) {
const auto schema = rfl::avro::to_schema<Licenses>();
const auto data = load_data();
for (auto _ : state) {
const auto output = rfl::avro::write(data, schema);
if (output.size() == 0) {
std::cout << "No output" << std::endl;
}
}
}
BENCHMARK(BM_licenses_write_reflect_cpp_avro);

static void BM_licenses_write_reflect_cpp_bson(benchmark::State &state) {
const auto data = load_data();
for (auto _ : state) {
Expand Down
13 changes: 13 additions & 0 deletions benchmarks/all/person_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <iostream>
#include <optional>
#include <rfl/avro.hpp>
#include <rfl/bson.hpp>
#include <rfl/cbor.hpp>
#include <rfl/flexbuf.hpp>
Expand Down Expand Up @@ -42,6 +43,18 @@ static Person load_data() {

// ----------------------------------------------------------------------------

static void BM_person_read_reflect_cpp_avro(benchmark::State &state) {
const auto schema = rfl::avro::to_schema<Person>();
const auto data = rfl::avro::write(load_data(), schema);
for (auto _ : state) {
const auto res = rfl::avro::read<Person>(data, schema);
if (!res) {
std::cout << res.error()->what() << std::endl;
}
}
}
BENCHMARK(BM_person_read_reflect_cpp_avro);

static void BM_person_read_reflect_cpp_bson(benchmark::State &state) {
const auto data = rfl::bson::write(load_data());
for (auto _ : state) {
Expand Down
13 changes: 13 additions & 0 deletions benchmarks/all/person_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <iostream>
#include <optional>
#include <rfl/avro.hpp>
#include <rfl/bson.hpp>
#include <rfl/cbor.hpp>
#include <rfl/flexbuf.hpp>
Expand Down Expand Up @@ -43,6 +44,18 @@ static Person load_data() {

// ----------------------------------------------------------------------------

static void BM_person_write_reflect_cpp_avro(benchmark::State &state) {
const auto schema = rfl::avro::to_schema<Person>();
const auto data = load_data();
for (auto _ : state) {
const auto output = rfl::avro::write(data, schema);
if (output.size() == 0) {
std::cout << "No output" << std::endl;
}
}
}
BENCHMARK(BM_person_write_reflect_cpp_avro);

static void BM_person_write_reflect_cpp_bson(benchmark::State &state) {
const auto data = load_data();
for (auto _ : state) {
Expand Down
3 changes: 3 additions & 0 deletions docs/concepts/custom_classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ If you want your class to be supported by reflect-cpp, it needs to have the foll
If you class fulfills these three conditions, then it is fully supported by all serialization and deserialization
routines in reflect-cpp.

Please be aware that due to limitations of the Avro format, it is a good idea to always have a struct as your
`ReflectionType` when using Avro to avoid infinite recursions.

If you absolutely do not want to make any changes to your original class, you can implement a [custom parser](https://github.com/getml/reflect-cpp/blob/main/docs/custom_parser.md).

## Example 1: Using an Impl struct
Expand Down
2 changes: 2 additions & 0 deletions docs/generic.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ reflect-cpp is intended to be used to directly parse into structs. Doing this is
But in some cases, we simply cannot anticipate the complete structure of the data at compile time. For these cases, we
have `rfl::Generic`.

Note that generics are not supported for Avro.

`rfl::Generic` is a convenience wrapper around the following type:

```cpp
Expand Down
10 changes: 1 addition & 9 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,9 @@ hide:
[![Generic badge](https://img.shields.io/badge/MSVC-17+-blue.svg)](https://shields.io/)
[![Conan Center](https://img.shields.io/conan/v/reflect-cpp)](https://conan.io/center/recipes/reflect-cpp)

**📖 Documentation**: [https://rfl.getml.com](https://rfl.getml.com)**👨‍💻 Source Code**: [https://github.com/getml/reflect-cpp](https://github.com/getml/reflect-cpp)

</div>

><br> **📣 From the Author (01.11.2024):** Hi everyone, Patrick ([liuzicheng1987](https://github.com/liuzicheng1987)) here. With reflect-cpp reaching the 1k-star milestone, we’re excited to roll out an overhauled documentation site at [https://rfl.getml.com](https://rfl.getml.com/), giving it a permanent place in our company. Initially developed as an internal tool for our machine learning library, [getML](https://getml.com), reflect-cpp has grown into something much larger.
<br> A big thank you to all contributors for helping us reach this point! Your feedback, ideas, and dedication have been invaluable.
<br> As we look to the project’s future, I would like to hear your thoughts on potential new directions, discuss ideas to expand our user base, or learn more about what you’re building with it. For the next month, I am opening a few slots in my calendar for anyone who wants to [connect (link)](https://calendar.app.google/AaeziooCNierbwAZ8).
<br> *— Best, Patrick*
<br>&nbsp;
<br>
**💻 Source Code**: [https://github.com/getml/reflect-cpp](https://github.com/getml/reflect-cpp)

**reflect-cpp** is a C++-20 library for **fast serialization, deserialization and validation** using reflection, similar to [pydantic](https://github.com/pydantic/pydantic) in Python, [serde](https://github.com/serde-rs) in Rust, [encoding](https://github.com/golang/go/tree/master/src/encoding) in Go or [aeson](https://github.com/haskell/aeson/tree/master) in Haskell.

Expand Down
3 changes: 2 additions & 1 deletion docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ To use reflect-cpp in your project:
```cmake
add_subdirectory(reflect-cpp) # Add this project as a subdirectory
set(REFLECTCPP_AVRO ON) # Optional
set(REFLECTCPP_BSON ON) # Optional
set(REFLECTCPP_CBOR ON) # Optional
set(REFLECTCPP_FLEXBUFFERS ON) # Optional
Expand Down Expand Up @@ -110,7 +111,7 @@ conan build . --build=missing -s compiler.cppstd=gnu20

You can call `conan inspect .` to get an overview of the supported options.

If you want to include all supported formats, do the following:
If you want to include all formats supported on Conan, do the following:

```bash
conan build . --build=missing -s compiler.cppstd=gnu20 -o *:with_cbor=True -o *:with_flatbuffers=True -o *:with_msgpack=True -o *:with_toml=True -o *:with_ubjson=True -o *:with_xml=True -o *:with_yaml=True
Expand Down
2 changes: 2 additions & 0 deletions docs/rfl_skip.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

It is possible to skip the serialization and deserialization of fields using `rfl::Skip`.

Note that `rfl::Skip` is unsupported by all schemaful formats, like Avro.

```cpp
struct Person {
rfl::Rename<"firstName", std::string> first_name;
Expand Down
Loading

0 comments on commit e1a47ed

Please sign in to comment.