Skip to content

Bug or possible regression with custom rfl::Reflectors #609

@FrancescoMerenda

Description

@FrancescoMerenda

After upgrading from 0.22 to 0.23 custom Reflectors for enum types (and basic types as well, but I'm not sure if that was possible before) are no longer considered.

With version 0.22 I was able to do the following:

enum class Role {
            Normal = 0,
            Admin = 1,
            SuperAdmin = 0xFF,
};

struct EditableUserFields {
            Role role;
            std::string firstname;
            std::string surname;
            std::string email;
};

namespace rfl {
template <>
struct Reflector<Api::Users::Role> {
    using ReflType = uint32_t;

    static Api::Users::Role to(const ReflType& v) {
        Api::Users::Role rv = static_cast<Api::Users::Role>(v);
        switch (rv) {
            case Api::Users::Role::Normal:
            case Api::Users::Role::Admin:
            case Api::Users::Role::SuperAdmin:
                return rv;
            default:
                throw "invalid role value";
        }
    }

    static ReflType from(const Api::Users::Role& v) {
        return static_cast<ReflType>(v);
    }
};
};

In the previous version that reflector would be used to correctly serialize the enum in to the numeric type.
In this version the reflector for the enum is completely ignored.
Reflectors for structs still works as expected.

I suspected it has to do with the fact that what was previously handled inside one template specialization is now handled in many different specializations.

After looking around I tried to edit the Parser_enum.hpp write function like this:

template <class P>
  static void write(const W& _w, const T& _var, const P& _parent) {
    if constexpr (internal::has_write_reflector<T>) {
      Parser<R, W, typename Reflector<T>::ReflType, ProcessorsType>::write(
          _w, Reflector<T>::from(_var), _parent);

    } else if constexpr (ProcessorsType::underlying_enums_ ||
                  schemaful::IsSchemafulWriter<W>) {
      const auto val = static_cast<std::underlying_type_t<T>>(_var);
      ParentType::add_value(_w, val, _parent);
    } else {
      const auto str = rfl::enum_to_string(_var);
      ParentType::add_value(_w, str, _parent);
    }
  }

fixes my issue.

I'm not sure but if this is the issue it would need to be done inside the read as well and maybe all the other checks of the Parser_default regarding custom reflectors or reflections types should be added here as well. But if that's the solution i'm not sure if this has affected the reflectors with other types as well or what that big changeset in 0.23 may do.

If need I'm willing to contribute with some guidance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions