diff --git a/CMakeLists.txt b/CMakeLists.txt index 71c8ce2b..30ba802b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.23) +cmake_minimum_required(VERSION 3.28) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -23,6 +23,7 @@ option(REFLECTCPP_YAML "Enable YAML support" ${REFLECTCPP_ALL_FORMATS}) option(REFLECTCPP_BUILD_BENCHMARKS "Build benchmarks" OFF) option(REFLECTCPP_BUILD_TESTS "Build tests" OFF) option(REFLECTCPP_CHECK_HEADERS "Make sure that all headers are self-contained" OFF) +option(REFLECTCPP_BUILD_MODULES "Build reflectcpp as a C++ module" OFF) option(REFLECTCPP_USE_BUNDLED_DEPENDENCIES "Use the bundled dependencies" ON) @@ -398,12 +399,17 @@ set_target_properties(reflectcpp PROPERTIES LINKER_LANGUAGE CXX) target_sources(reflectcpp PRIVATE ${REFLECT_CPP_SOURCES}) target_precompile_headers(reflectcpp PRIVATE [["rfl.hpp"]] ) +if (REFLECTCPP_BUILD_MODULES) + add_subdirectory(src/modules) +endif() + if (REFLECTCPP_BUILD_TESTS) add_library(reflectcpp_tests_crt INTERFACE) target_link_libraries(reflectcpp_tests_crt INTERFACE reflectcpp GTest::gtest_main) - + enable_testing() find_package(GTest CONFIG REQUIRED) + add_subdirectory(tests) endif () @@ -446,6 +452,7 @@ if(REFLECTCPP_CHECK_HEADERS) endforeach() endif() + if (REFLECTCPP_INSTALL) include(GNUInstallDirs) include(CMakePackageConfigHelpers) diff --git a/README.md b/README.md index f82b555b..c6d04003 100644 --- a/README.md +++ b/README.md @@ -588,6 +588,33 @@ In addition, it supports the following custom containers: Finally, it is very easy to extend full support to your own classes, refer to the [documentation](https://rfl.getml.com/docs-readme) for details. +### Module support + +reflect-cpp has support for C++20 modules. To enable, pass `REFLECTCPP_BUILD_MODULES` to CMake. You must have CMake 3.28 or higher, and any build system that supports modules (such as Ninja). + +```cpp +import std; +import rfl; + +using std::string; + +struct Person { + string first_name; + string last_name; + int age; +}; + +const Person homer = Person{ + .first_name = "Homer", + .last_name = "Simpson", + .age = 45 +}; + +// We can now write into and read from a JSON string. +const string json_string = rfl::json::write(homer); +auto homer2 = rfl::json::read(json_string).value(); +``` + ## Installation diff --git a/include/rfl/TaggedUnion.hpp b/include/rfl/TaggedUnion.hpp index 8df7267e..f1761ec2 100644 --- a/include/rfl/TaggedUnion.hpp +++ b/include/rfl/TaggedUnion.hpp @@ -17,6 +17,8 @@ struct TaggedUnion { /// The type of the underlying variant. using VariantType = rfl::Variant; + TaggedUnion() = default; + TaggedUnion(const VariantType& _variant) : variant_(_variant) {} TaggedUnion(VariantType&& _variant) noexcept diff --git a/include/rfl/capnproto/schema/CapnProtoTypes.hpp b/include/rfl/capnproto/schema/CapnProtoTypes.hpp index 6f50f4e6..959403a4 100644 --- a/include/rfl/capnproto/schema/CapnProtoTypes.hpp +++ b/include/rfl/capnproto/schema/CapnProtoTypes.hpp @@ -16,7 +16,7 @@ struct CapnProtoTypes { std::map unions_; }; -const char* MAP_DEFINITION = R"( +inline const char* MAP_DEFINITION = R"( struct Map(Value) { entries @0 :List(Entry); struct Entry { diff --git a/include/rfl/default.hpp b/include/rfl/default.hpp index fa6b1df1..9fcead52 100644 --- a/include/rfl/default.hpp +++ b/include/rfl/default.hpp @@ -7,7 +7,7 @@ namespace rfl { /// to trigger the default value of the type. struct Default {}; -inline static const auto default_value = Default{}; +inline const auto default_value = Default{}; } // namespace rfl diff --git a/include/rfl/parsing/call_destructors_on_array_where_necessary.hpp b/include/rfl/parsing/call_destructors_on_array_where_necessary.hpp index 1b02d3fd..27f7fc3d 100644 --- a/include/rfl/parsing/call_destructors_on_array_where_necessary.hpp +++ b/include/rfl/parsing/call_destructors_on_array_where_necessary.hpp @@ -1,3 +1,4 @@ + #ifndef RFL_PARSING_CALL_DESTRUCTORS_ON_ARRAY_WHERE_NECESSARY_HPP_ #define RFL_PARSING_CALL_DESTRUCTORS_ON_ARRAY_WHERE_NECESSARY_HPP_ diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt new file mode 100644 index 00000000..a29abce9 --- /dev/null +++ b/src/modules/CMakeLists.txt @@ -0,0 +1,96 @@ +cmake_minimum_required(VERSION 3.28) + +add_library(reflectcpp_module) + +set(MODULE_FILES) + +if(REFLECTCPP_JSON) + list(APPEND MODULE_FILES rfl.json.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_JSON) +endif() + +if(REFLECTCPP_AVRO) + list(APPEND MODULE_FILES rfl.avro.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_AVRO) +endif() + +if(REFLECTCPP_BSON) + list(APPEND MODULE_FILES rfl.bson.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_BSON) +endif() + +if(REFLECTCPP_CAPNPROTO) + list(APPEND MODULE_FILES rfl.capnproto.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_CAPNPROTO) +endif() + +if(REFLECTCPP_CBOR) + list(APPEND MODULE_FILES rfl.cbor.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_CBOR) +endif() + +if(REFLECTCPP_CSV) + list(APPEND MODULE_FILES rfl.csv.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_CSV) +endif() + +if(REFLECTCPP_FLEXBUFFERS) + list(APPEND MODULE_FILES rfl.flexbuf.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_FLEXBUFFERS) +endif() + +if(REFLECTCPP_MSGPACK) + list(APPEND MODULE_FILES rfl.msgpack.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_MSGPACK) +endif() + +if(REFLECTCPP_PARQUET) + list(APPEND MODULE_FILES rfl.parquet.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_PARQUET) +endif() + +if(REFLECTCPP_TOML) + list(APPEND MODULE_FILES rfl.toml.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_TOML) +endif() + +if(REFLECTCPP_UBJSON) + list(APPEND MODULE_FILES rfl.ubjson.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_UBJSON) +endif() + +if(REFLECTCPP_XML) + list(APPEND MODULE_FILES rfl.xml.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_XML) +endif() + +if(REFLECTCPP_YAML) + list(APPEND MODULE_FILES rfl.yaml.cppm) + target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_YAML) +endif() + +list(APPEND MODULE_FILES rfl.cppm) + +target_sources(reflectcpp_module + PUBLIC + FILE_SET CXX_MODULES FILES ${MODULE_FILES} +) + +target_compile_features(reflectcpp_module PUBLIC cxx_std_23) + +target_include_directories(reflectcpp_module PUBLIC + $ + $ +) + +target_link_libraries(reflectcpp_module PUBLIC reflectcpp::reflectcpp) + +add_library(reflectcpp::module ALIAS reflectcpp_module) + +install(TARGETS reflectcpp_module + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/src/module +) diff --git a/src/modules/rfl.avro.cppm b/src/modules/rfl.avro.cppm new file mode 100644 index 00000000..0a342e23 --- /dev/null +++ b/src/modules/rfl.avro.cppm @@ -0,0 +1,30 @@ +module; + +#ifdef REFLECTCPP_AVRO +#include "rfl/avro.hpp" +#include "rfl/avro/schema/Type.hpp" +#endif + +export module rfl:avro; + +export namespace rfl::avro { + #ifdef REFLECTCPP_AVRO + using rfl::avro::Parser; + using rfl::avro::Reader; + using rfl::avro::Schema; + using rfl::avro::Writer; + using rfl::avro::InputObjectType; + using rfl::avro::InputVarType; + + using rfl::avro::load; + using rfl::avro::read; + using rfl::avro::save; + using rfl::avro::to_json_representation; + using rfl::avro::to_schema; + using rfl::avro::write; + + namespace schema { + using rfl::avro::schema::Type; + } + #endif +} diff --git a/src/modules/rfl.bson.cppm b/src/modules/rfl.bson.cppm new file mode 100644 index 00000000..2da78c4d --- /dev/null +++ b/src/modules/rfl.bson.cppm @@ -0,0 +1,22 @@ +module; + +#ifdef REFLECTCPP_BSON +#include "rfl/bson.hpp" +#endif + +export module rfl:bson; + +export namespace rfl::bson { + #ifdef REFLECTCPP_BSON + using rfl::bson::Parser; + using rfl::bson::Reader; + using rfl::bson::Writer; + using rfl::bson::InputObjectType; + using rfl::bson::InputVarType; + + using rfl::bson::load; + using rfl::bson::read; + using rfl::bson::save; + using rfl::bson::write; + #endif +} diff --git a/src/modules/rfl.capnproto.cppm b/src/modules/rfl.capnproto.cppm new file mode 100644 index 00000000..106464a3 --- /dev/null +++ b/src/modules/rfl.capnproto.cppm @@ -0,0 +1,41 @@ +module; + +#ifdef REFLECTCPP_CAPNPROTO +#include "rfl/capnproto.hpp" +#include "rfl/capnproto/is_named_type.hpp" +#include "rfl/capnproto/schema/CapnProtoTypes.hpp" +#endif + +export module rfl:capnproto; + +export namespace rfl::capnproto { + #ifdef REFLECTCPP_CAPNPROTO + using rfl::capnproto::Parser; + using rfl::capnproto::Reader; + using rfl::capnproto::Schema; + using rfl::capnproto::SchemaImpl; + using rfl::capnproto::SchemaHolder; + using rfl::capnproto::Writer; + using rfl::capnproto::InputObjectType; + using rfl::capnproto::InputVarType; + + using rfl::capnproto::load; + using rfl::capnproto::read; + using rfl::capnproto::save; + using rfl::capnproto::to_schema; + using rfl::capnproto::write; + using rfl::capnproto::get_root_name; + using rfl::capnproto::is_named_type; + using rfl::capnproto::to_string_representation; + using rfl::capnproto::to_schema; + + namespace schema { + using rfl::capnproto::schema::CapnProtoTypes; + using rfl::capnproto::schema::Type; + + using rfl::capnproto::schema::MAP_DEFINITION; + + using rfl::capnproto::schema::operator<<; + } + #endif +} diff --git a/src/modules/rfl.cbor.cppm b/src/modules/rfl.cbor.cppm new file mode 100644 index 00000000..03851a35 --- /dev/null +++ b/src/modules/rfl.cbor.cppm @@ -0,0 +1,22 @@ +module; + +#ifdef REFLECTCPP_CBOR +#include "rfl/cbor.hpp" +#endif + +export module rfl:cbor; + +export namespace rfl::cbor { + #ifdef REFLECTCPP_CBOR + using rfl::cbor::Parser; + using rfl::cbor::Reader; + using rfl::cbor::Writer; + using rfl::cbor::InputObjectType; + using rfl::cbor::InputVarType; + + using rfl::cbor::load; + using rfl::cbor::read; + using rfl::cbor::save; + using rfl::cbor::write; + #endif +} diff --git a/src/modules/rfl.cppm b/src/modules/rfl.cppm new file mode 100644 index 00000000..f806ec41 --- /dev/null +++ b/src/modules/rfl.cppm @@ -0,0 +1,211 @@ +module; + +#include "rfl.hpp" + +export module rfl; + +#ifdef REFLECTCPP_AVRO +export import :avro; +#endif +#ifdef REFLECTCPP_BSON +export import :bson; +#endif +#ifdef REFLECTCPP_CAPNPROTO +export import :capnproto; +#endif +#ifdef REFLECTCPP_CBOR +export import :cbor; +#endif +#ifdef REFLECTCPP_CSV +export import :csv; +#endif +#ifdef REFLECTCPP_FLEXBUFFERS +export import :flexbuf; +#endif +#ifdef REFLECTCPP_JSON +export import :json; +#endif +#ifdef REFLECTCPP_MSGPACK +export import :msgpack; +#endif +#ifdef REFLECTCPP_PARQUET +export import :parquet; +#endif +#ifdef REFLECTCPP_TOML +export import :toml; +#endif +#ifdef REFLECTCPP_UBJSON +export import :ubjson; +#endif +#ifdef REFLECTCPP_XML +export import :xml; +#endif +#ifdef REFLECTCPP_YAML +export import :yaml; +#endif + +export namespace rfl { +using rfl::AddNamespacedTagsToVariants; +using rfl::AddStructName; +using rfl::AddTagsToVariants; +using rfl::AllOf; +using rfl::AllowRawPtrs; +using rfl::AlphaNumeric; +using rfl::AnyOf; +using rfl::Attribute; +using rfl::Base64Encoded; +using rfl::Binary; +using rfl::Box; +using rfl::Bytestring; +using rfl::Copyability; +using rfl::CopyableBox; +using rfl::Default; +using rfl::DefaultIfMissing; +using rfl::DefaultVal; +using rfl::Description; +using rfl::Email; +using rfl::EqualTo; +using rfl::Error; +using rfl::ExclusiveMaximum; +using rfl::ExclusiveMinimum; +using rfl::ExtraFields; +using rfl::Field; +using rfl::Flatten; +using rfl::Generic; +using rfl::Hex; +using rfl::Literal; +using rfl::LiteralHelper; +using rfl::Maximum; +using rfl::Minimum; +using rfl::NamedTuple; +using rfl::NoExtraFields; +using rfl::NoFieldNames; +using rfl::NoOptionals; +using rfl::NotEqualTo; +using rfl::Nothing; +using rfl::Object; +using rfl::Oct; +using rfl::OneOf; +using rfl::Pattern; +using rfl::PatternValidator; +using rfl::PossibleTags; +using rfl::Processors; +using rfl::Ref; +using rfl::Rename; +using rfl::Result; +using rfl::Size; +using rfl::Skip; +using rfl::SkipDeserialization; +using rfl::SkipSerialization; +using rfl::SnakeCaseToCamelCase; +using rfl::SnakeCaseToPascalCase; +using rfl::TaggedUnion; +using rfl::TaggedUnionBased; +using rfl::Timestamp; +using rfl::UnderlyingEnums; +using rfl::Unexpected; +using rfl::UUIDv1; +using rfl::UUIDv2; +using rfl::UUIDv3; +using rfl::UUIDv4; +using rfl::Validator; +using rfl::Variant; +using rfl::VariantBased; +using rfl::Vectorstring; + +using rfl::apply; +using rfl::as; +using rfl::enum_to_string; +using rfl::error; +using rfl::fields; +using rfl::from_generic; +using rfl::from_named_tuple; +using rfl::get; +using rfl::get_enum_range; +using rfl::get_enumerator_array; +using rfl::get_enumerators; +using rfl::get_if; +using rfl::get_underlying_enumerator_array; +using rfl::get_underlying_enumerators; +using rfl::holds_alternative; +using rfl::make_box; +using rfl::make_copyable_box; +using rfl::make_field; +using rfl::make_from_tuple; +using rfl::make_named_tuple; +using rfl::make_ref; +using rfl::name_of; +using rfl::replace; +using rfl::string_to_enum; +using rfl::to_array; +using rfl::to_bool; +using rfl::to_double; +using rfl::to_generic; +using rfl::to_int; +using rfl::to_int64; +using rfl::to_named_tuple; +using rfl::to_null; +using rfl::to_object; +using rfl::to_string; +using rfl::to_view; +using rfl::tuple_cat; +using rfl::value_of; +using rfl::visit; + +using rfl::always_false_v; +using rfl::default_value; +using rfl::define_literal_t; +using rfl::define_named_tuple_t; +using rfl::define_tagged_union_t; +using rfl::define_variant_t; +using rfl::extract_discriminators_t; +using rfl::field_type_t; +using rfl::name_t; +using rfl::named_tuple_t; +using rfl::possible_tags_t; +using rfl::remove_fields_t; +using rfl::type_name_t; +using rfl::variant_alternative; +using rfl::variant_alternative_t; +using rfl::variant_size; +using rfl::variant_size_v; +using rfl::view_t; + +using rfl::operator<=>; +using rfl::operator<<; +using rfl::operator*; +using rfl::operator==; + +namespace atomic { +using rfl::atomic::is_atomic_v; +using rfl::atomic::remove_atomic_t; +using rfl::atomic::set_atomic; +} // namespace atomic + +namespace concepts { +using rfl::concepts::BackInsertableByteContainer; +using rfl::concepts::ByteLike; +using rfl::concepts::ByteSpanLike; +using rfl::concepts::ContiguousByteContainer; +using rfl::concepts::MutableContiguousByteContainer; +} // namespace concepts + +namespace generic { +using rfl::generic::Parser; +using rfl::generic::Reader; +using rfl::generic::Writer; + +using rfl::generic::read; +using rfl::generic::write; +} // namespace generic + +} // namespace rfl + +export namespace std { +using std::hash; +using std::swap; + +#ifdef REFLECTCPP_USE_STD_EXPECTED +using std::bad_expected_access; +#endif +} // namespace std diff --git a/src/modules/rfl.csv.cppm b/src/modules/rfl.csv.cppm new file mode 100644 index 00000000..7c9821fa --- /dev/null +++ b/src/modules/rfl.csv.cppm @@ -0,0 +1,18 @@ +module; + +#ifdef REFLECTCPP_CSV +#include "rfl/csv.hpp" +#endif + +export module rfl:csv; + +export namespace rfl::csv { + #ifdef REFLECTCPP_CSV + using rfl::csv::Settings; + + using rfl::csv::load; + using rfl::csv::read; + using rfl::csv::save; + using rfl::csv::write; + #endif +} diff --git a/src/modules/rfl.flexbuf.cppm b/src/modules/rfl.flexbuf.cppm new file mode 100644 index 00000000..f040913a --- /dev/null +++ b/src/modules/rfl.flexbuf.cppm @@ -0,0 +1,21 @@ +module; + +#ifdef REFLECTCPP_FLEXBUFFERS +#include "rfl/flexbuf.hpp" +#endif + +export module rfl:flexbuf; + +export namespace rfl::flexbuf { + #ifdef REFLECTCPP_FLEXBUFFERS + using rfl::flexbuf::Parser; + using rfl::flexbuf::Reader; + using rfl::flexbuf::Writer; + + using rfl::flexbuf::load; + using rfl::flexbuf::read; + using rfl::flexbuf::save; + using rfl::flexbuf::to_buffer; + using rfl::flexbuf::write; + #endif +} diff --git a/src/modules/rfl.json.cppm b/src/modules/rfl.json.cppm new file mode 100644 index 00000000..357dab6d --- /dev/null +++ b/src/modules/rfl.json.cppm @@ -0,0 +1,31 @@ +module; + +#ifdef REFLECTCPP_JSON +#include "rfl/json.hpp" +#endif + +export module rfl:json; + +export namespace rfl::json { +#ifdef REFLECTCPP_JSON +using rfl::json::InputObjectType; +using rfl::json::InputVarType; +using rfl::json::Parser; +using rfl::json::Reader; +using rfl::json::TypeHelper; +using rfl::json::Writer; + +using rfl::json::pretty; + +using rfl::json::load; +using rfl::json::read; +using rfl::json::save; +using rfl::json::to_schema; +using rfl::json::write; + +namespace schema { +using rfl::json::schema::JSONSchema; +using rfl::json::schema::Type; +} // namespace schema +#endif +} // namespace rfl::json diff --git a/src/modules/rfl.msgpack.cppm b/src/modules/rfl.msgpack.cppm new file mode 100644 index 00000000..ebfa9705 --- /dev/null +++ b/src/modules/rfl.msgpack.cppm @@ -0,0 +1,22 @@ +module; + +#ifdef REFLECTCPP_MSGPACK +#include "rfl/msgpack.hpp" +#endif + +export module rfl:msgpack; + +export namespace rfl::msgpack { + #ifdef REFLECTCPP_MSGPACK + using rfl::msgpack::Parser; + using rfl::msgpack::Reader; + using rfl::msgpack::Writer; + using rfl::msgpack::InputObjectType; + using rfl::msgpack::InputVarType; + + using rfl::msgpack::load; + using rfl::msgpack::read; + using rfl::msgpack::save; + using rfl::msgpack::write; + #endif +} diff --git a/src/modules/rfl.parquet.cppm b/src/modules/rfl.parquet.cppm new file mode 100644 index 00000000..3433c97c --- /dev/null +++ b/src/modules/rfl.parquet.cppm @@ -0,0 +1,20 @@ +module; + +#ifdef REFLECTCPP_PARQUET +#include "rfl/parquet.hpp" +#endif + +export module rfl:parquet; + +export namespace rfl::parquet { + #ifdef REFLECTCPP_PARQUET + using rfl::parquet::Compression; + using rfl::parquet::Settings; + + using rfl::parquet::load; + using rfl::parquet::read; + using rfl::parquet::save; + using rfl::parquet::to_buffer; + using rfl::parquet::write; + #endif +} diff --git a/src/modules/rfl.toml.cppm b/src/modules/rfl.toml.cppm new file mode 100644 index 00000000..f68e4570 --- /dev/null +++ b/src/modules/rfl.toml.cppm @@ -0,0 +1,21 @@ +module; + +#ifdef REFLECTCPP_TOML +#include "rfl/toml.hpp" +#endif + +export module rfl:toml; + +export namespace rfl::toml { + #ifdef REFLECTCPP_TOML + using rfl::toml::Parser; + using rfl::toml::Reader; + using rfl::toml::Writer; + using rfl::toml::InputVarType; + + using rfl::toml::load; + using rfl::toml::read; + using rfl::toml::save; + using rfl::toml::write; + #endif +} diff --git a/src/modules/rfl.ubjson.cppm b/src/modules/rfl.ubjson.cppm new file mode 100644 index 00000000..186946c8 --- /dev/null +++ b/src/modules/rfl.ubjson.cppm @@ -0,0 +1,22 @@ +module; + +#ifdef REFLECTCPP_UBJSON +#include "rfl/ubjson.hpp" +#endif + +export module rfl:ubjson; + +export namespace rfl::ubjson { + #ifdef REFLECTCPP_UBJSON + using rfl::ubjson::Parser; + using rfl::ubjson::Reader; + using rfl::ubjson::Writer; + using rfl::ubjson::InputObjectType; + using rfl::ubjson::InputVarType; + + using rfl::ubjson::load; + using rfl::ubjson::read; + using rfl::ubjson::save; + using rfl::ubjson::write; + #endif +} diff --git a/src/modules/rfl.xml.cppm b/src/modules/rfl.xml.cppm new file mode 100644 index 00000000..15aab77a --- /dev/null +++ b/src/modules/rfl.xml.cppm @@ -0,0 +1,22 @@ +module; + +#ifdef REFLECTCPP_XML +#include "rfl/xml.hpp" +#endif + +export module rfl:xml; + +export namespace rfl::xml { + #ifdef REFLECTCPP_XML + using rfl::xml::Parser; + using rfl::xml::Reader; + using rfl::xml::Writer; + using rfl::xml::InputVarType; + + using rfl::xml::load; + using rfl::xml::read; + using rfl::xml::save; + using rfl::xml::get_root_name; + using rfl::xml::write; + #endif +} diff --git a/src/modules/rfl.yaml.cppm b/src/modules/rfl.yaml.cppm new file mode 100644 index 00000000..253ee5a5 --- /dev/null +++ b/src/modules/rfl.yaml.cppm @@ -0,0 +1,21 @@ +module; + +#ifdef REFLECTCPP_YAML +#include "rfl/yaml.hpp" +#endif + +export module rfl:yaml; + +export namespace rfl::yaml { + #ifdef REFLECTCPP_YAML + using rfl::yaml::Parser; + using rfl::yaml::Reader; + using rfl::yaml::Writer; + using rfl::yaml::InputVarType; + + using rfl::yaml::load; + using rfl::yaml::read; + using rfl::yaml::save; + using rfl::yaml::write; + #endif +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bfcab240..3d65cef8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,6 +20,10 @@ if (REFLECTCPP_BSON) add_subdirectory(bson) endif() +if (REFLECTCPP_BUILD_MODULES) + add_subdirectory(modules) +endif() + if (REFLECTCPP_CAPNPROTO) add_subdirectory(capnproto) endif() diff --git a/tests/avro/test_box.cpp b/tests/avro/test_box.cpp index 151f8583..9c38a17b 100644 --- a/tests/avro/test_box.cpp +++ b/tests/avro/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(avro, test_box) { diff --git a/tests/avro/test_flatten.cpp b/tests/avro/test_flatten.cpp index 4325afad..678b56a3 100644 --- a/tests/avro/test_flatten.cpp +++ b/tests/avro/test_flatten.cpp @@ -7,15 +7,15 @@ namespace test_flatten { struct Person { - rfl::Field<"firstName", std::string> first_name; - rfl::Field<"lastName", rfl::Box> last_name; - rfl::Field<"age", int> age; + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", rfl::Box> last_name; + rfl::Rename<"age", int> age; }; struct Employee { rfl::Flatten person; - rfl::Field<"employer", rfl::Box> employer; - rfl::Field<"salary", float> salary; + rfl::Rename<"employer", rfl::Box> employer; + rfl::Rename<"salary", float> salary; }; TEST(avro, test_flatten) { diff --git a/tests/bson/test_box.cpp b/tests/bson/test_box.cpp index 148ff54a..4dcb4e39 100644 --- a/tests/bson/test_box.cpp +++ b/tests/bson/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(bson, test_box) { @@ -36,6 +36,5 @@ TEST(bson, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box diff --git a/tests/bson/test_ref.cpp b/tests/bson/test_ref.cpp index 6f6fc1bc..3c1c1756 100644 --- a/tests/bson/test_ref.cpp +++ b/tests/bson/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(bson, test_ref) { +TEST(bson, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(bson, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref diff --git a/tests/cbor/test_box.cpp b/tests/cbor/test_box.cpp index 64e7ff16..ef5903c9 100644 --- a/tests/cbor/test_box.cpp +++ b/tests/cbor/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(cbor, test_box) { @@ -36,6 +36,5 @@ TEST(cbor, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box diff --git a/tests/cbor/test_ref.cpp b/tests/cbor/test_ref.cpp index 60d434b5..f895c6b9 100644 --- a/tests/cbor/test_ref.cpp +++ b/tests/cbor/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(cbor, test_ref) { +TEST(cbor, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(cbor, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref diff --git a/tests/flexbuffers/test_box.cpp b/tests/flexbuffers/test_box.cpp index fdfd8994..019ead2b 100644 --- a/tests/flexbuffers/test_box.cpp +++ b/tests/flexbuffers/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(flexbuf, test_box) { @@ -36,6 +36,5 @@ TEST(flexbuf, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box diff --git a/tests/flexbuffers/test_ref.cpp b/tests/flexbuffers/test_ref.cpp index c02ccf90..fc216ac7 100644 --- a/tests/flexbuffers/test_ref.cpp +++ b/tests/flexbuffers/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(flexbuf, test_ref) { +TEST(flexbuf, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(flexbuf, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref diff --git a/tests/generic/test_box.cpp b/tests/generic/test_box.cpp index e91fae93..405604c4 100644 --- a/tests/generic/test_box.cpp +++ b/tests/generic/test_box.cpp @@ -20,10 +20,9 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; - TEST(generic, test_box) { auto leaf1 = DecisionTree::Leaf{.value = 3.0}; @@ -37,13 +36,10 @@ TEST(generic, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box - -namespace test_copyable_box -{ +namespace test_copyable_box { struct DecisionTree { struct Leaf { using Tag = rfl::Literal<"Leaf">; @@ -59,8 +55,9 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; + TEST(generic, copyable_box) { auto leaf1 = DecisionTree::Leaf{.value = 3.0}; @@ -77,12 +74,18 @@ TEST(generic, copyable_box) { const DecisionTree tree2 = tree1; - auto lesser_leaf_tree2 = rfl::get(rfl::get(tree2.leaf_or_node.get().variant()).lesser.get()->leaf_or_node.get().variant()); + auto lesser_leaf_tree2 = rfl::get( + rfl::get(tree2.leaf_or_node().variant()) + .lesser.get() + ->leaf_or_node.get() + .variant()); lesser_leaf_tree2.value = 1.0; - - auto lesser_leaf_tree1 = rfl::get(rfl::get(tree1.leaf_or_node.get().variant()).lesser.get()->leaf_or_node.get().variant()); + auto lesser_leaf_tree1 = rfl::get( + rfl::get(tree1.leaf_or_node().variant()) + .lesser.get() + ->leaf_or_node.get() + .variant()); EXPECT_NE(lesser_leaf_tree1.value, lesser_leaf_tree2.value); - } -} // namespace test_copyable_box +} // namespace test_copyable_box diff --git a/tests/generic/test_ref.cpp b/tests/generic/test_ref.cpp index 8acf2441..d84e290d 100644 --- a/tests/generic/test_ref.cpp +++ b/tests/generic/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(generic, test_ref) { +TEST(generic, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(generic, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref diff --git a/tests/json/test_box.cpp b/tests/json/test_box.cpp index dd9bd6d5..c6d7b153 100644 --- a/tests/json/test_box.cpp +++ b/tests/json/test_box.cpp @@ -22,7 +22,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(json, test_box) { @@ -35,7 +35,7 @@ TEST(json, test_box) { .lesser = rfl::make_box(DecisionTree{leaf1}), .greater = rfl::make_box(DecisionTree{leaf2})}; - const DecisionTree tree{.leaf_or_node = std::move(node)}; + const auto tree = DecisionTree{.leaf_or_node = std::move(node)}; write_and_read( tree, diff --git a/tests/json/test_ref.cpp b/tests/json/test_ref.cpp index 44906546..c55c462a 100644 --- a/tests/json/test_ref.cpp +++ b/tests/json/test_ref.cpp @@ -22,7 +22,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(json, test_ref) { diff --git a/tests/modules/CMakeLists.txt b/tests/modules/CMakeLists.txt new file mode 100644 index 00000000..fcf61504 --- /dev/null +++ b/tests/modules/CMakeLists.txt @@ -0,0 +1,71 @@ +cmake_minimum_required(VERSION 3.28) + +add_executable(reflect-cpp-modules-tests) + +if(REFLECTCPP_JSON) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_JSON) +endif() + +if(REFLECTCPP_AVRO) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_AVRO) +endif() + +if(REFLECTCPP_BSON) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_BSON) +endif() + +if(REFLECTCPP_CAPNPROTO) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_CAPNPROTO) +endif() + +if(REFLECTCPP_CBOR) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_CBOR) +endif() + +if(REFLECTCPP_CSV) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_CSV) +endif() + +if(REFLECTCPP_FLEXBUFFERS) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_FLEXBUFFERS) +endif() + +if(REFLECTCPP_MSGPACK) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_MSGPACK) +endif() + +if(REFLECTCPP_PARQUET) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_PARQUET) +endif() + +if(REFLECTCPP_TOML) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_TOML) +endif() + +if(REFLECTCPP_UBJSON) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_UBJSON) +endif() + +if(REFLECTCPP_XML) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_XML) +endif() + +if(REFLECTCPP_YAML) + target_compile_definitions(reflect-cpp-modules-tests PUBLIC REFLECTCPP_YAML) +endif() + + +target_include_directories(reflect-cpp-modules-tests PUBLIC + $ + $ +) + +file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") + +target_sources(reflect-cpp-modules-tests PUBLIC ${SOURCES}) + +target_link_libraries(reflect-cpp-modules-tests PUBLIC reflectcpp_module reflectcpp_tests_crt) + +find_package(GTest) + +gtest_discover_tests(reflect-cpp-modules-tests) diff --git a/tests/modules/test_bson.cpp b/tests/modules/test_bson.cpp new file mode 100644 index 00000000..3410c229 --- /dev/null +++ b/tests/modules/test_bson.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_BSON + +#include + +#include +#include +#include + +import rfl; + +namespace test_bson { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_bson) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto bson_bytes = rfl::bson::write(homer); + const auto homer2 = rfl::bson::read(bson_bytes).value(); + const auto bson_bytes2 = rfl::bson::write(homer2); + + ASSERT_EQ(bson_bytes, bson_bytes2); +} + +} // namespace test_bson + +#endif // REFLECTCPP_MSGPACK diff --git a/tests/modules/test_cbor.cpp b/tests/modules/test_cbor.cpp new file mode 100644 index 00000000..bb849bd4 --- /dev/null +++ b/tests/modules/test_cbor.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_CBOR + +#include + +#include +#include +#include + +import rfl; + +namespace test_cbor { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_cbor) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto cbor_bytes = rfl::cbor::write(homer); + const auto homer2 = rfl::cbor::read(cbor_bytes).value(); + const auto cbor_bytes2 = rfl::cbor::write(homer2); + + ASSERT_EQ(cbor_bytes, cbor_bytes2); +} + +} // namespace test_cbor + +#endif // REFLECTCPP_MSGPACK diff --git a/tests/modules/test_flexbuffers.cpp b/tests/modules/test_flexbuffers.cpp new file mode 100644 index 00000000..c93de80d --- /dev/null +++ b/tests/modules/test_flexbuffers.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_FLEXBUFFERS + +#include + +#include +#include +#include + +import rfl; + +namespace test_flexbuffers { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_flexbuffers) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto flexbuffers_bytes = rfl::flexbuf::write(homer); + const auto homer2 = rfl::flexbuf::read(flexbuffers_bytes).value(); + const auto flexbuffers_bytes2 = rfl::flexbuf::write(homer2); + + ASSERT_EQ(flexbuffers_bytes, flexbuffers_bytes2); +} + +} // namespace test_flexbuffers + +#endif // REFLECTCPP_MSGPACK diff --git a/tests/modules/test_json.cpp b/tests/modules/test_json.cpp new file mode 100644 index 00000000..fa8a9441 --- /dev/null +++ b/tests/modules/test_json.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_JSON + +#include + +#include +#include +#include + +import rfl; + +namespace test_json { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_json) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto json_str = rfl::json::write(homer); + const auto homer2 = rfl::json::read(json_str).value(); + const auto json_str2 = rfl::json::write(homer2); + + ASSERT_EQ(json_str, json_str2); +} + +} // namespace test_json + +#endif // REFLECTCPP_JSON diff --git a/tests/modules/test_msgpack.cpp b/tests/modules/test_msgpack.cpp new file mode 100644 index 00000000..69c06163 --- /dev/null +++ b/tests/modules/test_msgpack.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_MSGPACK + +#include + +#include +#include +#include + +import rfl; + +namespace test_msgpack { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_msgpack) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto msgpack_bytes = rfl::msgpack::write(homer); + const auto homer2 = rfl::msgpack::read(msgpack_bytes).value(); + const auto msgpack_bytes2 = rfl::msgpack::write(homer2); + + ASSERT_EQ(msgpack_bytes, msgpack_bytes2); +} + +} // namespace test_msgpack + +#endif // REFLECTCPP_MSGPACK diff --git a/tests/modules/test_toml.cpp b/tests/modules/test_toml.cpp new file mode 100644 index 00000000..2161b137 --- /dev/null +++ b/tests/modules/test_toml.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_TOML + +#include + +#include +#include +#include + +import rfl; + +namespace test_toml { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_toml) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto toml_str = rfl::toml::write(homer); + const auto homer2 = rfl::toml::read(toml_str).value(); + const auto toml_str2 = rfl::toml::write(homer2); + + ASSERT_EQ(toml_str, toml_str2); +} + +} // namespace test_toml + +#endif // REFLECTCPP_JSON diff --git a/tests/modules/test_ubjson.cpp b/tests/modules/test_ubjson.cpp new file mode 100644 index 00000000..6b9ede61 --- /dev/null +++ b/tests/modules/test_ubjson.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_UBJSON + +#include + +#include +#include +#include + +import rfl; + +namespace test_ubjson { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_ubjson) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto ubjson_bytes = rfl::ubjson::write(homer); + const auto homer2 = rfl::ubjson::read(ubjson_bytes).value(); + const auto ubjson_bytes2 = rfl::ubjson::write(homer2); + + ASSERT_EQ(ubjson_bytes, ubjson_bytes2); +} + +} // namespace test_ubjson + +#endif // REFLECTCPP_MSGPACK diff --git a/tests/modules/test_xml.cpp b/tests/modules/test_xml.cpp new file mode 100644 index 00000000..7c65d75a --- /dev/null +++ b/tests/modules/test_xml.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_XML + +#include + +#include +#include +#include + +import rfl; + +namespace test_xml { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_xml) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto xml_str = rfl::xml::write(homer); + const auto homer2 = rfl::xml::read(xml_str).value(); + const auto xml_str2 = rfl::xml::write(homer2); + + ASSERT_EQ(xml_str, xml_str2); +} + +} // namespace test_xml + +#endif // REFLECTCPP_JSON diff --git a/tests/modules/test_yaml.cpp b/tests/modules/test_yaml.cpp new file mode 100644 index 00000000..12d304f4 --- /dev/null +++ b/tests/modules/test_yaml.cpp @@ -0,0 +1,57 @@ +#ifdef REFLECTCPP_YAML + +#include + +#include +#include +#include + +import rfl; + +namespace test_yaml { + +using Age = rfl::Validator, rfl::Maximum<130>>; + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Simpson"; + std::string town = "Springfield"; + rfl::Timestamp<"%Y-%m-%d"> birthday; + Age age; + rfl::Email email; + std::vector children; +}; + +TEST(modules, test_yaml) { + const auto bart = Person{.first_name = "Bart", + .birthday = "1987-04-19", + .age = 10, + .email = "bart@simpson.com"}; + + const auto lisa = Person{.first_name = "Lisa", + .birthday = "1987-04-19", + .age = 8, + .email = "lisa@simpson.com"}; + + const auto maggie = Person{.first_name = "Maggie", + .birthday = "1987-04-19", + .age = 0, + .email = "maggie@simpson.com"}; + + const auto homer = + Person{.first_name = "Homer", + .birthday = "1987-04-19", + .age = 45, + .email = "homer@simpson.com", + .children = std::vector({bart, lisa, maggie})}; + + const auto yaml_str = rfl::yaml::write(homer); + const auto homer2 = rfl::yaml::read(yaml_str).value(); + const auto yaml_str2 = rfl::yaml::write(homer2); + + ASSERT_EQ(yaml_str, yaml_str2); +} + +} // namespace test_yaml + +#endif // REFLECTCPP_JSON diff --git a/tests/msgpack/test_box.cpp b/tests/msgpack/test_box.cpp index bb2737c4..b27739d8 100644 --- a/tests/msgpack/test_box.cpp +++ b/tests/msgpack/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(msgpack, test_box) { @@ -36,6 +36,5 @@ TEST(msgpack, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box diff --git a/tests/msgpack/test_ref.cpp b/tests/msgpack/test_ref.cpp index f56e1cdd..eab2e333 100644 --- a/tests/msgpack/test_ref.cpp +++ b/tests/msgpack/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(msgpack, test_ref) { +TEST(msgpack, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(msgpack, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref diff --git a/tests/toml/test_box.cpp b/tests/toml/test_box.cpp index 724986de..8206a7de 100644 --- a/tests/toml/test_box.cpp +++ b/tests/toml/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(toml, test_box) { @@ -36,6 +36,5 @@ TEST(toml, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box diff --git a/tests/toml/test_ref.cpp b/tests/toml/test_ref.cpp index 7bec77f7..453e10d7 100644 --- a/tests/toml/test_ref.cpp +++ b/tests/toml/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(toml, test_ref) { +TEST(toml, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(toml, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref diff --git a/tests/ubjson/test_box.cpp b/tests/ubjson/test_box.cpp index 13431adc..468532c1 100644 --- a/tests/ubjson/test_box.cpp +++ b/tests/ubjson/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(ubjson, test_box) { @@ -36,6 +36,5 @@ TEST(ubjson, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box diff --git a/tests/ubjson/test_ref.cpp b/tests/ubjson/test_ref.cpp index ca7a15c0..9f921d59 100644 --- a/tests/ubjson/test_ref.cpp +++ b/tests/ubjson/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(ubjson, test_ref) { +TEST(ubjson, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(ubjson, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref diff --git a/tests/xml/test_box.cpp b/tests/xml/test_box.cpp index 969b2d2f..834df833 100644 --- a/tests/xml/test_box.cpp +++ b/tests/xml/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(xml, test_box) { @@ -36,6 +36,5 @@ TEST(xml, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box diff --git a/tests/xml/test_ref.cpp b/tests/xml/test_ref.cpp index 320ce069..02e17aef 100644 --- a/tests/xml/test_ref.cpp +++ b/tests/xml/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(xml, test_ref) { +TEST(xml, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(xml, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref diff --git a/tests/yaml/test_box.cpp b/tests/yaml/test_box.cpp index fc04dcec..de9c507e 100644 --- a/tests/yaml/test_box.cpp +++ b/tests/yaml/test_box.cpp @@ -20,7 +20,7 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; TEST(yaml, test_box) { @@ -36,6 +36,5 @@ TEST(yaml, test_box) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_box diff --git a/tests/yaml/test_ref.cpp b/tests/yaml/test_ref.cpp index 558b23ee..ba54cdde 100644 --- a/tests/yaml/test_ref.cpp +++ b/tests/yaml/test_ref.cpp @@ -20,10 +20,10 @@ struct DecisionTree { using LeafOrNode = rfl::TaggedUnion<"type", Leaf, Node>; - rfl::Field<"leafOrNode", LeafOrNode> leaf_or_node; + rfl::Rename<"leafOrNode", LeafOrNode> leaf_or_node; }; -TEST(yaml, test_ref) { +TEST(yaml, test_ref) { const auto leaf1 = DecisionTree::Leaf{.value = 3.0}; const auto leaf2 = DecisionTree::Leaf{.value = 5.0}; @@ -36,6 +36,5 @@ TEST(yaml, test_ref) { const DecisionTree tree{.leaf_or_node = std::move(node)}; write_and_read(tree); - } } // namespace test_ref