#ifndef RFL_ANYOF_HPP_ #define RFL_ANYOF_HPP_ #include #include #include #include "Result.hpp" #include "parsing/schema/ValidationType.hpp" namespace rfl { /// Requires that all of the contraints C and Cs be true. template struct AnyOf { template static rfl::Result validate(const T& _value) noexcept { return validate_impl(_value, {}); } template static parsing::schema::ValidationType to_schema() { using ValidationType = parsing::schema::ValidationType; const auto types = std::vector( {C::template to_schema(), Cs::template to_schema()...} ); return ValidationType {ValidationType::AnyOf {.types_ = types}}; } private: static Error make_error_message(const std::vector& _errors) { std::string msg = "Expected at least one of the following validations to pass, but " "none " "of them did:"; for (size_t i = 0; i < _errors.size(); ++i) { msg += "\n" + std::to_string(i + 1) + ") " + _errors.at(i).what(); } return Error(msg); } template static rfl::Result validate_impl(const T& _value, std::vector _errors) { const auto handle_err = [&](Error&& _err) { _errors.push_back(std::forward(_err)); if constexpr (sizeof...(Tail) == 0) { return make_error_message(_errors); } else { return validate_impl( _value, std::forward>(_errors) ); } }; return Head::validate(_value).or_else(handle_err); } }; } // namespace rfl #endif