From 4698ab90337466184e7fddab4511bc361002627c Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Sun, 4 Feb 2024 06:36:18 +0100 Subject: [PATCH] Began developing the JSON schema definition; #25 --- include/rfl/Field.hpp | 3 + include/rfl/internal/schema/Definition.hpp | 21 +++++++ include/rfl/internal/schema/Type.hpp | 62 +++++++++++++++++++ include/rfl/internal/schema/make.hpp | 69 ++++++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 include/rfl/internal/schema/Definition.hpp create mode 100644 include/rfl/internal/schema/Type.hpp create mode 100644 include/rfl/internal/schema/make.hpp diff --git a/include/rfl/Field.hpp b/include/rfl/Field.hpp index ae190b30..30c09c12 100644 --- a/include/rfl/Field.hpp +++ b/include/rfl/Field.hpp @@ -65,6 +65,9 @@ struct Field { /// Returns the underlying object. const Type& get() const { return value_; } + /// Returns the name of the fiels as a string. + static std::string name() const { return name_::str(); } + /// Returns the underlying object. Type& operator()() { return value_; } diff --git a/include/rfl/internal/schema/Definition.hpp b/include/rfl/internal/schema/Definition.hpp new file mode 100644 index 00000000..f888b2b5 --- /dev/null +++ b/include/rfl/internal/schema/Definition.hpp @@ -0,0 +1,21 @@ +#ifndef RFL_INTERNAL_SCHEMA_DEFINITION_HPP_ +#define RFL_INTERNAL_SCHEMA_DEFINITION_HPP_ + +#include +#include + +#include "Type.hpp" + +namespace rfl::internal::schema { + +struct Definition { + /// Contains the root element of the schema definition. + Type root_; + + /// Contains the definitions to be referenced by Type::Reference. + std::map definitions_; +}; + +} // namespace rfl::internal::schema + +#endif diff --git a/include/rfl/internal/schema/Type.hpp b/include/rfl/internal/schema/Type.hpp new file mode 100644 index 00000000..a2b80595 --- /dev/null +++ b/include/rfl/internal/schema/Type.hpp @@ -0,0 +1,62 @@ +#ifndef RFL_INTERNAL_SCHEMA_TYPE_HPP_ +#define RFL_INTERNAL_SCHEMA_TYPE_HPP_ + +#include +#include +#include +#include + +#include "../../Ref.hpp" + +namespace rfl::internal::schema { + +struct Type { + struct Int32 {}; + + struct Int64 {}; + + struct UInt32 {}; + + struct UInt64 {}; + + struct Integer {}; + + struct Float {}; + + struct Double {}; + + struct String {}; + + struct Object { + std::map types_; + }; + + /// All values are assumed to be required unless explicitly stated otherwise + /// using this wrapper. + struct Optional { + Ref type_; + }; + + /// The is necessary to resolve circular definitions. Refers to something in + /// Definitions. + struct Reference { + std::string name_; + }; + + struct TypedArray { + Ref type_; + }; + + struct Variant { + std::vector types_; + }; + + /// A type can be determined to be any of the above. + std::variant + variant_; +}; + +} // namespace rfl::internal::schema + +#endif diff --git a/include/rfl/internal/schema/make.hpp b/include/rfl/internal/schema/make.hpp new file mode 100644 index 00000000..334e343a --- /dev/null +++ b/include/rfl/internal/schema/make.hpp @@ -0,0 +1,69 @@ +#ifndef RFL_INTERNAL_SCHEMA_MAKE_HPP_ +#define RFL_INTERNAL_SCHEMA_MAKE_HPP_ + +#include + +#include +#include +#include +#include +#include + +#include "../../parsing/is_required.hpp" +#include "../is_named_tuple.hpp" +#include "Type.hpp" + +namespace rfl::internal::schema { + +template +Type make_type(std::map* _definitions); + +template +Type make_named_tuple_type(std::map* _definitions, + std::map _values = {}) { + constexpr size_t size = T::size(); + if constexpr (_i == size) { + return Type{Object{_values}}; + } else { + using F = std::tuple_element_t<_i, typename T::Fields>; + _values[F::name()] = make_type(_definitions); + return make_named_tuple_type(_definitions, _values); + } +}; + +template +Type make_type(std::map* _definitions) { + using U = std::remove_cvref_t; + if constexpr (std::is_same()) { + return Definition{.root_ = Type{Int32{}}}; + } else if constexpr (std::is_same()) { + return Definition{.root_ = Type{Int64{}}}; + } else if constexpr (std::is_same()) { + return Definition{.root_ = Type{UInt32{}}}; + } else if constexpr (std::is_same()) { + return Definition{.root_ = Type{UInt64{}}}; + } else if constexpr (std::is_integral()) { + return Definition{.root_ = Type{Integer{}}}; + } else if constexpr (std::is_same()) { + return Definition{.root_ = Type{Float{}}}; + } else if constexpr (std::is_same()) { + return Definition{.root_ = Type{Double{}}}; + } else if constexpr (std::is_same()) { + return Definition{.root_ = Type{String{}}}; + } else if constexpr (is_named_tuple_v) { + return make_named_tuple_definition(); + } else if constexpr (!is_required()) { + // TODO + } +} + +template +Definition make() { + std::map definitions; + auto root = make_type(&definitions); + return Definition{.root_ = root, .definitions_ = definitions}; +} + +} // namespace rfl::internal::schema + +#endif