Skip to content

Commit

Permalink
Began developing rfl::StripFieldNames
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Urbanke committed Jun 10, 2024
1 parent d8549e8 commit 07bbb32
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 26 deletions.
1 change: 1 addition & 0 deletions include/rfl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "rfl/Skip.hpp"
#include "rfl/SnakeCaseToCamelCase.hpp"
#include "rfl/SnakeCaseToPascalCase.hpp"
#include "rfl/StripFieldNames.hpp"
#include "rfl/TaggedUnion.hpp"
#include "rfl/Timestamp.hpp"
#include "rfl/Validator.hpp"
Expand Down
6 changes: 6 additions & 0 deletions include/rfl/Processors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <type_traits>

#include "internal/is_no_optionals_v.hpp"
#include "internal/is_strip_field_names_v.hpp"

namespace rfl {

Expand All @@ -13,6 +14,7 @@ struct Processors;
template <>
struct Processors<> {
static constexpr bool all_required_ = false;
static constexpr bool strip_field_names_ = false;

template <class T, class NamedTupleType>
static auto process(NamedTupleType&& _named_tuple) {
Expand All @@ -26,6 +28,10 @@ struct Processors<Head, Tail...> {
std::disjunction_v<internal::is_no_optionals<Head>,
internal::is_no_optionals<Tail>...>;

static constexpr bool strip_field_names_ =
std::disjunction_v<internal::is_strip_field_names<Head>,
internal::is_strip_field_names<Tail>...>;

template <class T, class NamedTupleType>
static auto process(NamedTupleType&& _named_tuple) {
return Processors<Tail...>::template process<T>(
Expand Down
18 changes: 18 additions & 0 deletions include/rfl/StripFieldNames.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef RFL_STRIPFIELDNAMES_HPP_
#define RFL_STRIPFIELDNAMES_HPP_

namespace rfl {

/// This is a "fake" processor - it doesn't do much in itself, but its
/// inclusion instructs the parsers to strip field names.
struct StripFieldNames {
public:
template <class StructType>
static auto process(auto&& _named_tuple) {
return _named_tuple;
}
};

} // namespace rfl

#endif
10 changes: 6 additions & 4 deletions include/rfl/cbor/Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ requires AreReaderAndWriter<cbor::Reader, cbor::Writer,
NamedTuple<FieldTypes...>>
struct Parser<cbor::Reader, cbor::Writer, NamedTuple<FieldTypes...>,
ProcessorsType>
: public NamedTupleParser<cbor::Reader, cbor::Writer,
/*_ignore_empty_containers=*/false,
/*_all_required=*/true, ProcessorsType,
FieldTypes...> {
: public NamedTupleParser<
cbor::Reader, cbor::Writer,
/*_ignore_empty_containers=*/false,
/*_all_required=*/true,
/*_strip_field_names=*/ProcessorsType::strip_field_names_,
ProcessorsType, FieldTypes...> {
};

template <class ProcessorsType, class... Ts>
Expand Down
29 changes: 29 additions & 0 deletions include/rfl/internal/is_strip_field_names_v.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef RFL_INTERNAL_ISSTRIPFIELDNAMES_HPP_
#define RFL_INTERNAL_ISSTRIPFIELDNAMES_HPP_

#include <tuple>
#include <type_traits>
#include <utility>

#include "../StripFieldNames.hpp"

namespace rfl {
namespace internal {

template <class T>
class is_strip_field_names;

template <class T>
class is_strip_field_names : public std::false_type {};

template <>
class is_strip_field_names<StripFieldNames> : public std::true_type {};

template <class T>
constexpr bool is_strip_field_names_v =
is_strip_field_names<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;

} // namespace internal
} // namespace rfl

#endif
10 changes: 6 additions & 4 deletions include/rfl/msgpack/Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ requires AreReaderAndWriter<msgpack::Reader, msgpack::Writer,
NamedTuple<FieldTypes...>>
struct Parser<msgpack::Reader, msgpack::Writer, NamedTuple<FieldTypes...>,
ProcessorsType>
: public NamedTupleParser<msgpack::Reader, msgpack::Writer,
/*_ignore_empty_containers=*/false,
/*_all_required=*/true, ProcessorsType,
FieldTypes...> {
: public NamedTupleParser<
msgpack::Reader, msgpack::Writer,
/*_ignore_empty_containers=*/false,
/*_all_required=*/true,
/*_strip_field_names=*/ProcessorsType::strip_field_names_,
ProcessorsType, FieldTypes...> {
};

template <class ProcessorsType, class... Ts>
Expand Down
49 changes: 35 additions & 14 deletions include/rfl/parsing/NamedTupleParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "Parent.hpp"
#include "Parser_base.hpp"
#include "ViewReader.hpp"
#include "ViewReaderWithStrippedFieldNames.hpp"
#include "is_empty.hpp"
#include "is_required.hpp"
#include "schema/Type.hpp"
Expand All @@ -31,10 +32,9 @@ namespace rfl {
namespace parsing {

template <class R, class W, bool _ignore_empty_containers, bool _all_required,
class ProcessorsType, class... FieldTypes>
bool _strip_field_names, class ProcessorsType, class... FieldTypes>
requires AreReaderAndWriter<R, W, NamedTuple<FieldTypes...>>
struct NamedTupleParser {
using InputObjectType = typename R::InputObjectType;
using InputVarType = typename R::InputVarType;

using OutputObjectType = typename W::OutputObjectType;
Expand All @@ -44,6 +44,15 @@ struct NamedTupleParser {

using NamedTupleType = NamedTuple<FieldTypes...>;

using ViewReaderType = std::conditional_t<
_strip_field_names,
ViewReaderWithStrippedFieldNames<R, W, NamedTupleType, ProcessorsType>,
ViewReader<R, W, NamedTupleType, ProcessorsType>>;

using InputObjectOrArrayType =
std::conditional_t<_strip_field_names, typename R::InputArrayType,
typename R::InputObjectType>;

static constexpr size_t size_ = NamedTupleType::size();

public:
Expand All @@ -70,11 +79,19 @@ struct NamedTupleParser {
static std::optional<Error> read_view(
const R& _r, const InputVarType& _var,
NamedTuple<FieldTypes...>* _view) noexcept {
auto obj = _r.to_object(_var);
if (!obj) [[unlikely]] {
return obj.error();
if constexpr (_strip_field_names) {
auto arr = _r.to_array(_var);
if (!arr) [[unlikely]] {
return arr.error();
}
return read_object_or_array(_r, *arr, _view);
} else {
auto obj = _r.to_object(_var);
if (!obj) [[unlikely]] {
return obj.error();
}
return read_object_or_array(_r, *obj, _view);
}
return read_object(_r, *obj, _view);
}

/// For writing, we do not need to make the distinction between
Expand Down Expand Up @@ -185,24 +202,28 @@ struct NamedTupleParser {
(handle_one_missing_field<_is>(_found, _view, _set, _errors), ...);
}

static std::optional<Error> read_object(const R& _r,
const InputObjectType& _obj,
NamedTupleType* _view) noexcept {
static std::optional<Error> read_object_or_array(
const R& _r, const InputObjectOrArrayType& _obj_or_arr,
NamedTupleType* _view) noexcept {
auto found = std::array<bool, NamedTupleType::size()>();
found.fill(false);
auto set = std::array<bool, NamedTupleType::size()>();
set.fill(false);
std::vector<Error> errors;
const auto object_reader = ViewReader<R, W, NamedTupleType, ProcessorsType>(
&_r, _view, &found, &set, &errors);
const auto err = _r.read_object(object_reader, _obj);
const auto reader = ViewReaderType(&_r, _view, &found, &set, &errors);
std::optional<Error> err;
if constexpr (_strip_field_names) {
err = _r.read_array(reader, _obj_or_arr);
} else {
err = _r.read_object(reader, _obj_or_arr);
}
if (err) {
return *err;
return err;
}
handle_missing_fields(found, *_view, &set, &errors,
std::make_integer_sequence<int, size_>());
if (errors.size() != 0) {
object_reader.call_destructors_where_necessary();
reader.call_destructors_where_necessary();
return to_single_error_message(errors);
}
return std::nullopt;
Expand Down
8 changes: 5 additions & 3 deletions include/rfl/parsing/Parser_named_tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ namespace parsing {
template <class R, class W, class... FieldTypes, class ProcessorsType>
requires AreReaderAndWriter<R, W, NamedTuple<FieldTypes...>>
struct Parser<R, W, NamedTuple<FieldTypes...>, ProcessorsType>
: public NamedTupleParser<R, W, /*_ignore_empty_containers=*/false,
/*_all_required=*/ProcessorsType::all_required_,
ProcessorsType, FieldTypes...> {
: public NamedTupleParser<
R, W, /*_ignore_empty_containers=*/false,
/*_all_required=*/ProcessorsType::all_required_,
/*_strip_field_names=*/ProcessorsType::strip_field_names_,
ProcessorsType, FieldTypes...> {
};

} // namespace parsing
Expand Down
Loading

0 comments on commit 07bbb32

Please sign in to comment.