#ifndef RFL_PARSING_PARSER_RESULT_HPP_ #define RFL_PARSING_PARSER_RESULT_HPP_ #include #include #include "../Result.hpp" #include "../always_false.hpp" #include "../internal/StringLiteral.hpp" #include "Parser_base.hpp" #include "schema/Type.hpp" namespace rfl { namespace parsing { template requires AreReaderAndWriter> struct Parser, ProcessorsType> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; using ErrorType = NamedTuple>; using VariantType = std::variant, ErrorType>; static Result> read(const R& _r, const InputVarType& _var) noexcept { const auto handle = [](auto&& _t) -> Result { using Type = std::remove_cvref_t; if constexpr (std::is_same()) { return Error(_t.template get<"error">()); } else { return std::forward>(_t); } }; const auto to_res = [&](VariantType&& _v) -> Result { return std::visit(handle, std::forward(_v)); }; return Result>( Parser::read(_r, _var).transform( to_res)); } template static void write(const W& _w, const Result& _r, const P& _parent) noexcept { const auto write_t = [&](const auto& _t) -> Nothing { Parser, ProcessorsType>::write(_w, _t, _parent); return Nothing {}; }; const auto write_err = [&](const auto& _err) -> Nothing { Parser::write( _w, ErrorType(make_field<"error">(_err.what())), _parent); return Nothing {}; }; _r.transform(write_t).or_else(write_err); } static schema::Type to_schema( std::map* _definitions) { return Parser, ProcessorsType>::to_schema( _definitions); } }; } // namespace parsing } // namespace rfl #endif