Skip to content

Commit dfcbff9

Browse files
Added support for JSON schemata for the Reflector type; fixes #509 (#527)
1 parent 83951fd commit dfcbff9

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

include/rfl/parsing/Parser_default.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ struct Parser {
193193
} else if constexpr (internal::is_validator_v<U>) {
194194
return make_validated<U>(_definitions);
195195

196-
} else if constexpr (internal::has_reflection_type_v<U>) {
196+
} else if constexpr (internal::has_reflection_type_v<U> ||
197+
internal::has_read_reflector<U> ||
198+
internal::has_write_reflector<U>) {
197199
return make_reference<U>(_definitions);
198200

199201
} else {
@@ -235,13 +237,21 @@ struct Parser {
235237
std::map<std::string, schema::Type>* _definitions) {
236238
using Type = schema::Type;
237239
const auto name = make_type_name<U>();
240+
238241
if (_definitions->find(name) == _definitions->end()) {
239242
(*_definitions)[name] =
240243
Type{Type::Integer{}}; // Placeholder to avoid infinite loop.
244+
241245
if constexpr (internal::has_reflection_type_v<U>) {
242246
(*_definitions)[name] =
243247
Parser<R, W, typename U::ReflectionType, ProcessorsType>::to_schema(
244248
_definitions);
249+
250+
} else if constexpr (internal::has_read_reflector<U> ||
251+
internal::has_write_reflector<U>) {
252+
(*_definitions)[name] = Parser<R, W, typename Reflector<U>::ReflType,
253+
ProcessorsType>::to_schema(_definitions);
254+
245255
} else {
246256
using NamedTupleType = internal::processed_t<U, ProcessorsType>;
247257
(*_definitions)[name] =

include/rfl/parsing/make_type_name.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
#include "../type_name_t.hpp"
55
#include "is_tagged_union_wrapper.hpp"
66

7-
namespace rfl {
8-
namespace parsing {
7+
namespace rfl::parsing {
98

109
inline std::string replace_non_alphanumeric(std::string _str) {
1110
for (auto& ch : _str) {
@@ -24,7 +23,6 @@ static std::string make_type_name() {
2423
}
2524
}
2625

27-
} // namespace parsing
28-
} // namespace rfl
26+
} // namespace rfl::parsing
2927

3028
#endif
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <cassert>
2+
#include <rfl.hpp>
3+
#include <rfl/json.hpp>
4+
#include <string>
5+
#include <vector>
6+
7+
#include "write_and_read.hpp"
8+
9+
namespace test_reflector_schema {
10+
11+
struct Person {
12+
std::string first_name = "Homer";
13+
std::string last_name = "Simpson";
14+
};
15+
16+
struct Parent : Person {
17+
public:
18+
std::vector<Person> children;
19+
};
20+
21+
} // namespace test_reflector_schema
22+
23+
namespace rfl {
24+
template <>
25+
struct Reflector<test_reflector_schema::Parent> {
26+
struct ReflType {
27+
std::string first_name;
28+
std::string last_name;
29+
std::vector<test_reflector_schema::Person> children;
30+
};
31+
32+
static ReflType from(const test_reflector_schema::Parent& v) {
33+
return {v.first_name, v.last_name, v.children};
34+
}
35+
};
36+
} // namespace rfl
37+
38+
namespace test_reflector_schema {
39+
40+
TEST(json, test_reflector_schema) {
41+
const std::string expected =
42+
R"({"$schema":"https://json-schema.org/draft/2020-12/schema","$ref":"#/$defs/test_reflector_schema__Parent","$defs":{"rfl__Reflector_test_reflector_schema__Parent___ReflType":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"children":{"type":"array","items":{"$ref":"#/$defs/test_reflector_schema__Person"}}},"required":["first_name","last_name","children"]},"test_reflector_schema__Parent":{"$ref":"#/$defs/rfl__Reflector_test_reflector_schema__Parent___ReflType"},"test_reflector_schema__Person":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"}},"required":["first_name","last_name"]}}})";
43+
44+
const std::string expected_windows =
45+
R"({"$schema":"https://json-schema.org/draft/2020-12/schema","$ref":"#/$defs/test_reflector_schema__Parent","$defs":{"rfl__Reflector_struct_test_reflector_schema__Parent___ReflType":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"children":{"type":"array","items":{"$ref":"#/$defs/test_reflector_schema__Person"}}},"required":["first_name","last_name","children"]},"test_reflector_schema__Parent":{"$ref":"#/$defs/rfl__Reflector_struct_test_reflector_schema__Parent___ReflType"},"test_reflector_schema__Person":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"}},"required":["first_name","last_name"]}}})";
46+
47+
EXPECT_TRUE(rfl::json::to_schema<Parent>() == expected ||
48+
rfl::json::to_schema<Parent>() == expected_windows);
49+
}
50+
} // namespace test_reflector_schema

0 commit comments

Comments
 (0)