Skip to content

Commit

Permalink
Added (basic) support for variants
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzicheng1987 committed Dec 29, 2024
1 parent e5020bf commit c8defbf
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 15 deletions.
26 changes: 15 additions & 11 deletions include/rfl/capnproto/schema/Type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,8 @@ struct Type {

struct Data {};

struct Optional {
rfl::Ref<Type> type;
};

struct Text {};

struct Struct {
std::string name;
std::vector<std::pair<std::string, Type>> fields;
};

struct List {
rfl::Ref<Type> type;
};
Expand All @@ -60,14 +51,27 @@ struct Type {
rfl::Ref<Type> type;
};

struct Optional {
rfl::Ref<Type> type;
};

struct Reference {
std::string type_name;
};

struct Struct {
std::string name;
std::vector<std::pair<std::string, Type>> fields;
};

struct Variant {
std::vector<Type> types;
};

using ReflectionType =
rfl::Variant<Void, Bool, Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32,
UInt64, Float32, Float64, Data, Text, Struct, List, /*Map,*/
Optional, Reference>;
UInt64, Float32, Float64, Data, Text, List,
/*Map,*/ Optional, Reference, Struct, Variant>;

const auto& reflection() const { return value; }

Expand Down
11 changes: 11 additions & 0 deletions src/rfl/capnproto/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ std::ostream& operator<<(std::ostream& _os, const Type::Struct& _s) {
<< " some @" << ix++ << " :" << *_r.type << ";" << std::endl
<< " none @" << ix++ << " :Void;" << std::endl
<< " }" << std::endl;
} else if constexpr (std::is_same<R, Type::Variant>()) {
_os << " " << name << " :union {" << std::endl;
for (size_t i = 0; i < _r.types.size(); ++i) {
_os << " option" << i + 1 << " @" << ix++ << " :" << _r.types[i]
<< ";" << std::endl;
}
_os << " }" << std::endl;
} else {
_os << " " << name << " @" << ix++ << " :" << _r << ";" << std::endl;
}
Expand All @@ -129,6 +136,10 @@ std::ostream& operator<<(std::ostream& _os, const Type::List& _l) {
return _os << "List(" << *_l.type << ")";
}

std::ostream& operator<<(std::ostream& _os, const Type::Variant& _v) {
return _os << "TODO";
}

std::ostream& operator<<(std::ostream& _os, const Type::Reference& _r) {
return _os << internal::strings::to_pascal_case(_r.type_name);
}
Expand Down
4 changes: 2 additions & 2 deletions src/rfl/capnproto/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Writer::OutputObjectType Writer::add_object_to_union(
OutputUnionType* _parent) const noexcept {
const auto field = _parent->val_.getSchema().getFields()[_index];
return OutputObjectType{
_parent->val_.get(field).template as<capnp::DynamicStruct>()};
_parent->val_.init(field).template as<capnp::DynamicStruct>()};
}

Writer::OutputUnionType Writer::add_union_to_array(
Expand All @@ -135,7 +135,7 @@ Writer::OutputUnionType Writer::add_union_to_union(
const size_t _index, OutputUnionType* _parent) const noexcept {
const auto field = _parent->val_.getSchema().getFields()[_index];
return OutputUnionType{
_parent->val_.get(field).template as<capnp::DynamicStruct>()};
_parent->val_.init(field).template as<capnp::DynamicStruct>()};
}

Writer::OutputVarType Writer::add_null_to_array(
Expand Down
13 changes: 11 additions & 2 deletions src/rfl/capnproto/to_schema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,12 @@ schema::Type type_to_capnproto_schema_type(
return schema::Type{.value = schema::Type::Text{}};

} else if constexpr (std::is_same<T, Type::AnyOf>()) {
// TODO
return schema::Type{.value = schema::Type::Void{}};
auto value = schema::Type::Variant{};
for (const auto& type : _t.types_) {
value.types.push_back(
type_to_capnproto_schema_type(type, _definitions, _num_unnamed));
}
return schema::Type{.value = value};

} else if constexpr (std::is_same<T, Type::Description>()) {
return type_to_capnproto_schema_type(*_t.type_, _definitions,
Expand Down Expand Up @@ -115,9 +119,11 @@ schema::Type type_to_capnproto_schema_type(
.value = schema::Type::Optional{
.type = Ref<schema::Type>::make(type_to_capnproto_schema_type(
*_t.type_, _definitions, _num_unnamed))}};

} else if constexpr (std::is_same<T, Type::Reference>()) {
return schema::Type{.value =
schema::Type::Reference{.type_name = _t.name_}};

} else if constexpr (std::is_same<T, Type::StringMap>()) {
// TODO
return schema::Type{.value = schema::Type::Void{}};
Expand All @@ -126,15 +132,18 @@ schema::Type type_to_capnproto_schema_type(
.values = Ref<schema::Type>::make(type_to_capnproto_schema_type(
*_t.value_type_, _definitions,
_num_unnamed))}};*/

} else if constexpr (std::is_same<T, Type::Tuple>()) {
return type_to_capnproto_schema_type(
Type{parsing::schemaful::tuple_to_object(_t)}, _definitions,
_num_unnamed);

} else if constexpr (std::is_same<T, Type::TypedArray>()) {
return schema::Type{
.value = schema::Type::List{
.type = Ref<schema::Type>::make(type_to_capnproto_schema_type(
*_t.type_, _definitions, _num_unnamed))}};

} else if constexpr (std::is_same<T, Type::Validated>()) {
// Cap'n Proto knows no validation.
return type_to_capnproto_schema_type(*_t.type_, _definitions,
Expand Down
33 changes: 33 additions & 0 deletions tests/capnproto/test_variant.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <cassert>
#include <iostream>
#include <rfl.hpp>
#include <string>
#include <vector>

#include "write_and_read.hpp"

namespace test_variant {

struct Circle {
double radius;
};

struct Rectangle {
double height;
double width;
};

struct Square {
double width;
};

struct Shapes {
std::variant<Circle, Rectangle, Square> root;
};

TEST(capnproto, test_variant) {
const auto r = Shapes{Rectangle{.height = 10, .width = 5}};

write_and_read(r);
}
} // namespace test_variant

0 comments on commit c8defbf

Please sign in to comment.