Skip to content

Commit 5aeaef5

Browse files
Begin developing yas support
1 parent 498d9d0 commit 5aeaef5

12 files changed

Lines changed: 611 additions & 1 deletion

File tree

CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ option(REFLECTCPP_XML "Enable XML support" ${REFLECTCPP_ALL_FORMATS})
2121
option(REFLECTCPP_TOML "Enable TOML support" ${REFLECTCPP_ALL_FORMATS})
2222
option(REFLECTCPP_UBJSON "Enable UBJSON support" ${REFLECTCPP_ALL_FORMATS})
2323
option(REFLECTCPP_YAML "Enable YAML support" ${REFLECTCPP_ALL_FORMATS})
24+
option(REFLECTCPP_YAS "Enable yas support" ${REFLECTCPP_ALL_FORMATS})
2425
option(REFLECTCPP_BOOST_SERIALIZATION "Enable Boost.Serialization support" ${REFLECTCPP_ALL_FORMATS})
2526

2627
option(REFLECTCPP_BUILD_BENCHMARKS "Build benchmarks" OFF)
@@ -58,6 +59,7 @@ if(REFLECTCPP_BUILD_BENCHMARKS)
5859
set(REFLECTCPP_TOML ON CACHE BOOL "" FORCE)
5960
set(REFLECTCPP_UBJSON ON CACHE BOOL "" FORCE)
6061
set(REFLECTCPP_YAML ON CACHE BOOL "" FORCE)
62+
set(REFLECTCPP_YAS ON CACHE BOOL "" FORCE)
6163
set(REFLECTCPP_BOOST_SERIALIZATION ON CACHE BOOL "" FORCE)
6264
endif()
6365

@@ -79,7 +81,8 @@ if (
7981
REFLECTCPP_XML OR
8082
REFLECTCPP_TOML OR
8183
REFLECTCPP_UBJSON OR
82-
REFLECTCPP_YAML
84+
REFLECTCPP_YAML OR
85+
REFLECTCPP_YAS
8386
)
8487
# enable vcpkg per default if features other than JSON are required
8588
set(REFLECTCPP_USE_VCPKG_DEFAULT ON)
@@ -166,6 +169,10 @@ if (REFLECTCPP_USE_VCPKG)
166169
list(APPEND VCPKG_MANIFEST_FEATURES "yaml")
167170
endif()
168171

172+
if (REFLECTCPP_YAS OR REFLECTCPP_CHECK_HEADERS)
173+
list(APPEND VCPKG_MANIFEST_FEATURES "yas")
174+
endif()
175+
169176
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file")
170177
endif ()
171178

@@ -438,6 +445,13 @@ if (REFLECTCPP_BOOST_SERIALIZATION OR REFLECTCPP_CHECK_HEADERS)
438445
target_link_libraries(reflectcpp PUBLIC Boost::serialization)
439446
endif ()
440447

448+
if (REFLECTCPP_YAS OR REFLECTCPP_CHECK_HEADERS)
449+
if (NOT TARGET yas::yas)
450+
find_package(yas CONFIG REQUIRED)
451+
endif ()
452+
target_link_libraries(reflectcpp PUBLIC yas::yas)
453+
endif ()
454+
441455
set_target_properties(reflectcpp PROPERTIES LINKER_LANGUAGE CXX)
442456
target_sources(reflectcpp PRIVATE ${REFLECT_CPP_SOURCES})
443457
target_precompile_headers(reflectcpp PRIVATE [["rfl.hpp"]] <iostream> <string> <functional>)

include/rfl/yas.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef RFL_YAS_HPP_
2+
#define RFL_YAS_HPP_
3+
4+
#include "../rfl.hpp"
5+
#include "yas/Parser.hpp"
6+
#include "yas/Reader.hpp"
7+
#include "yas/Writer.hpp"
8+
#include "yas/load.hpp"
9+
#include "yas/read.hpp"
10+
#include "yas/save.hpp"
11+
#include "yas/write.hpp"
12+
13+
#endif

include/rfl/yas/Parser.hpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#ifndef RFL_YAS_PARSER_HPP_
2+
#define RFL_YAS_PARSER_HPP_
3+
4+
#include "../Generic.hpp"
5+
#include "../NamedTuple.hpp"
6+
#include "../Tuple.hpp"
7+
#include "../always_false.hpp"
8+
#include "../parsing/Parser.hpp"
9+
#include "Reader.hpp"
10+
#include "Writer.hpp"
11+
12+
namespace rfl {
13+
namespace parsing {
14+
15+
template <class IArchive, class OArchive, class ProcessorsType,
16+
class... FieldTypes>
17+
requires AreReaderAndWriter<yas::Reader<IArchive>, yas::Writer<OArchive>,
18+
NamedTuple<FieldTypes...>>
19+
struct Parser<yas::Reader<IArchive>, yas::Writer<OArchive>,
20+
NamedTuple<FieldTypes...>, ProcessorsType>
21+
: public NamedTupleParser<yas::Reader<IArchive>, yas::Writer<OArchive>,
22+
/*_ignore_empty_containers=*/false,
23+
/*_all_required=*/true,
24+
/*_no_field_names=*/true, ProcessorsType,
25+
FieldTypes...> {};
26+
27+
template <class IArchive, class OArchive, class ProcessorsType, class... Ts>
28+
requires AreReaderAndWriter<yas::Reader<IArchive>, yas::Writer<OArchive>,
29+
rfl::Tuple<Ts...>>
30+
struct Parser<yas::Reader<IArchive>, yas::Writer<OArchive>, rfl::Tuple<Ts...>,
31+
ProcessorsType>
32+
: public TupleParser<yas::Reader<IArchive>, yas::Writer<OArchive>,
33+
/*_ignore_empty_containers=*/false,
34+
/*_all_required=*/true, ProcessorsType,
35+
rfl::Tuple<Ts...>> {};
36+
37+
template <class IArchive, class OArchive, class ProcessorsType, class... Ts>
38+
requires AreReaderAndWriter<yas::Reader<IArchive>, yas::Writer<OArchive>,
39+
std::tuple<Ts...>>
40+
struct Parser<yas::Reader<IArchive>, yas::Writer<OArchive>, std::tuple<Ts...>,
41+
ProcessorsType>
42+
: public TupleParser<yas::Reader<IArchive>, yas::Writer<OArchive>,
43+
/*_ignore_empty_containers=*/false,
44+
/*_all_required=*/true, ProcessorsType,
45+
std::tuple<Ts...>> {};
46+
47+
template <class IArchive, class OArchive, class ProcessorsType>
48+
requires AreReaderAndWriter<yas::Reader<IArchive>, yas::Writer<OArchive>,
49+
Generic>
50+
struct Parser<yas::Reader<IArchive>, yas::Writer<OArchive>, Generic,
51+
ProcessorsType> {
52+
template <class T>
53+
static Result<Generic> read(const yas::Reader<IArchive>&, const T&) noexcept {
54+
static_assert(always_false_v<T>, "Generics are unsupported in yas.");
55+
return error("Unsupported");
56+
}
57+
58+
template <class P>
59+
static void write(const yas::Writer<OArchive>&, const Generic&,
60+
const P&) noexcept {
61+
static_assert(always_false_v<P>, "Generics are unsupported in yas.");
62+
}
63+
64+
template <class T>
65+
static schema::Type to_schema(T*) {
66+
static_assert(always_false_v<T>, "Generics are unsupported in yas.");
67+
return schema::Type{};
68+
}
69+
};
70+
71+
} // namespace parsing
72+
} // namespace rfl
73+
74+
#endif

include/rfl/yas/Reader.hpp

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#ifndef RFL_YAS_READER_HPP_
2+
#define RFL_YAS_READER_HPP_
3+
4+
#include <cstdint>
5+
#include <optional>
6+
#include <string>
7+
#include <string_view>
8+
#include <type_traits>
9+
10+
#include "../Result.hpp"
11+
#include "../always_false.hpp"
12+
#include "../internal/is_literal.hpp"
13+
#include "../parsing/schemaful/IsSchemafulReader.hpp"
14+
15+
namespace rfl::yas {
16+
17+
template <class IArchive>
18+
struct Reader {
19+
struct InputVarType {
20+
IArchive* ar;
21+
};
22+
23+
struct InputArrayType {
24+
IArchive* ar;
25+
};
26+
27+
struct InputObjectType {
28+
IArchive* ar;
29+
};
30+
31+
struct InputMapType {
32+
IArchive* ar;
33+
};
34+
35+
struct InputUnionType {
36+
IArchive* ar;
37+
};
38+
39+
template <class T>
40+
static constexpr bool has_custom_constructor = false;
41+
42+
bool is_empty(const InputVarType& /*_var*/) const noexcept { return false; }
43+
44+
template <class T>
45+
rfl::Result<T> to_basic_type(const InputVarType& _var) const noexcept {
46+
try {
47+
if constexpr (internal::is_literal_v<T>) {
48+
std::string str;
49+
(*_var.ar) & str;
50+
return std::remove_cvref_t<T>::from_string(str);
51+
} else {
52+
T value;
53+
(*_var.ar) & value;
54+
return value;
55+
}
56+
} catch (std::exception& e) {
57+
return error(std::string("yas read error: ") + e.what());
58+
}
59+
}
60+
61+
rfl::Result<InputArrayType> to_array(
62+
const InputVarType& _var) const noexcept {
63+
return InputArrayType{_var.ar};
64+
}
65+
66+
rfl::Result<InputObjectType> to_object(
67+
const InputVarType& _var) const noexcept {
68+
return InputObjectType{_var.ar};
69+
}
70+
71+
rfl::Result<InputMapType> to_map(const InputVarType& _var) const noexcept {
72+
return InputMapType{_var.ar};
73+
}
74+
75+
rfl::Result<InputUnionType> to_union(
76+
const InputVarType& _var) const noexcept {
77+
return InputUnionType{_var.ar};
78+
}
79+
80+
template <class ArrayReader>
81+
std::optional<Error> read_array(const ArrayReader& _array_reader,
82+
const InputArrayType& _arr) const noexcept {
83+
try {
84+
std::size_t size;
85+
(*_arr.ar) & size;
86+
for (std::size_t i = 0; i < size; ++i) {
87+
const auto err = _array_reader.read(InputVarType{_arr.ar});
88+
if (err) {
89+
return err;
90+
}
91+
}
92+
return std::nullopt;
93+
} catch (std::exception& e) {
94+
return Error(std::string("yas array read error: ") + e.what());
95+
}
96+
}
97+
98+
template <class MapReader>
99+
std::optional<Error> read_map(const MapReader& _map_reader,
100+
const InputMapType& _map) const noexcept {
101+
try {
102+
std::size_t size;
103+
(*_map.ar) & size;
104+
for (std::size_t i = 0; i < size; ++i) {
105+
std::string key;
106+
(*_map.ar) & key;
107+
_map_reader.read(std::string_view(key), InputVarType{_map.ar});
108+
}
109+
return std::nullopt;
110+
} catch (std::exception& e) {
111+
return Error(std::string("yas map read error: ") + e.what());
112+
}
113+
}
114+
115+
template <class ObjectReader>
116+
std::optional<Error> read_object(const ObjectReader& _object_reader,
117+
const InputObjectType& _obj) const noexcept {
118+
try {
119+
for (size_t i = 0; i < ObjectReader::size(); ++i) {
120+
_object_reader.read(i, InputVarType{_obj.ar});
121+
}
122+
return std::nullopt;
123+
} catch (std::exception& e) {
124+
return Error(std::string("yas object read error: ") + e.what());
125+
}
126+
}
127+
128+
template <class T, class UnionReader>
129+
rfl::Result<T> read_union(const InputUnionType& _union) const noexcept {
130+
try {
131+
std::size_t index;
132+
(*_union.ar) & index;
133+
return UnionReader::read(*this, index, InputVarType{_union.ar});
134+
} catch (std::exception& e) {
135+
return error(std::string("yas union read error: ") + e.what());
136+
}
137+
}
138+
139+
template <class T>
140+
rfl::Result<T> use_custom_constructor(
141+
const InputVarType& /*_var*/) const noexcept {
142+
return rfl::error("Custom constructors are not supported.");
143+
}
144+
};
145+
146+
} // namespace rfl::yas
147+
148+
#endif

0 commit comments

Comments
 (0)