beached / daw_json_link

Fast, convenient JSON serialization and parsing in C++
https://beached.github.io/daw_json_link/
Boost Software License 1.0
478 stars 31 forks source link

Can't link enum class for some reason #227

Closed 0xBYTESHIFT closed 3 years ago

0xBYTESHIFT commented 3 years ago

Here's the code:

#include <iostream>
#include <daw/json/daw_json_link.h>

namespace api
{

    struct request
    {
        const static inline std::string type = "request";
        enum class code
        {
            OK,
            ERROR
        };
        code c;
    };
};

namespace daw::json
{
    template <>
    struct json_data_contract<api::request>
    {
        static constexpr char const name_type[] = "type";
        static constexpr char const name_code[] = "code";

        using type = json_member_list<
            json_string<name_type>,
            json_number<name_code>>;

        static inline auto to_json_data(const api::request &value)
        {
            return std::forward_as_tuple(
                value.type,
                value.c);
        }
    };
} // namespace daw::json

int main(int, char **)
{
    auto data = "{ \"type\":\"request\", \"code\":0 }";
    auto req = daw::json::from_json<api::request>(data);
    std::cout << daw::json::to_json(req) << "\n";
}

Why can't I use enums with json_number? Making enum class something : int{} doesn't help either.

It produces compile errors like that:

Errors ``` FAILED: CMakeFiles/example.dir/main.cpp.o /bin/clang++-11 -I_deps/daw_json_link-src/include -I_deps/daw_utf_range-src/include -isystem _deps/daw_header_libraries-src/include -g -std=gnu++17 -MD -MT CMakeFiles/example.dir/main.cpp.o -MF CMakeFiles/example.dir/main.cpp.o.d -o CMakeFiles/example.dir/main.cpp.o -c ../main.cpp In file included from ../main.cpp:2: In file included from _deps/daw_json_link-src/include/daw/json/daw_json_link.h:10: In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json.h:11: In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json_fwd.h:11: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_types_fwd.h:12: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_impl.h:12: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_assert.h:11: In file included from _deps/daw_json_link-src/include/daw/json/daw_json_exception.h:12: In file included from _deps/daw_header_libraries-src/include/daw/daw_string_view.h:11: In file included from _deps/daw_header_libraries-src/include/daw/iterator/../daw_algorithm.h:11: In file included from _deps/daw_header_libraries-src/include/daw/iterator/../cpp_17.h:19: /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/tuple:1727:14: error: no matching function for call to '__invoke' return std::__invoke(std::forward<_Fn>(__f), ^~~~~~~~~~~~~ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/tuple:1738:19: note: in instantiation of function template specialization 'std::__apply_impl &, std::tuple &&, double &&>, 0, 1>' requested here return std::__apply_impl(std::forward<_Fn>(__f), ^ _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_impl.h:488:29: note: in instantiation of function template specialization 'std::apply &, std::tuple &&, double &&>>' requested here JsonClass result = std::apply( ^ _deps/daw_json_link-src/include/daw/json/daw_json_link_types.h:70:25: note: in instantiation of function template specialization 'daw::json::json_details::parse_json_class::name_type, std::__cxx11::basic_string, daw::json::default_constructor>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>, daw::json::json_number<&daw::json::json_data_contract::name_code, double, daw::json::LiteralAsStringOpt::Never, daw::json::default_constructor, daw::json::JsonRangeCheck::Never, daw::json::JsonNullable::Never>, 0, 1, daw::json::BasicParsePolicy, daw::json::constexpr_exec_tag, false, daw::json::json_details::NoAllocator>>' requested here return json_details::parse_json_class( ^ _deps/daw_json_link-src/include/daw/json/impl/daw_json_parse_value.h:450:28: note: in instantiation of function template specialization 'daw::json::json_member_list::name_type, std::__cxx11::basic_string, daw::json::default_constructor>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>, daw::json::json_number<&daw::json::json_data_contract::name_code, double, daw::json::LiteralAsStringOpt::Never, daw::json::default_constructor, daw::json::JsonRangeCheck::Never, daw::json::JsonNullable::Never>>::parse_to_class, daw::json::constexpr_exec_tag, false, daw::json::json_details::NoAllocator>>' requested here element_t>::template parse_to_class( rng ); ^ _deps/daw_json_link-src/include/daw/json/daw_from_json.h:42:24: note: in instantiation of function template specialization 'daw::json::json_details::parse_value, daw::json::JsonNullable::Never>, false, daw::json::BasicParsePolicy, daw::json::constexpr_exec_tag, false, daw::json::json_details::NoAllocator>>' requested here return json_details::parse_value( ^ ../main.cpp:43:27: note: in instantiation of function template specialization 'daw::json::from_json, daw::json::constexpr_exec_tag, false, daw::json::json_details::NoAllocator>, false, api::request>' requested here auto req = daw::json::from_json(data); ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:89:5: note: candidate template ignored: substitution failure [with _Callable = const daw::json::default_constructor &, _Args = , double>]: no type named 'type' in 'std::__invoke_result &, std::__cxx11::basic_string, double>' __invoke(_Callable&& __fn, _Args&&... __args) ^ In file included from ../main.cpp:2: In file included from _deps/daw_json_link-src/include/daw/json/daw_json_link.h:10: In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json.h:11: In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json_fwd.h:11: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_types_fwd.h:12: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_impl.h:16: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_serialize_impl.h:10: _deps/daw_json_link-src/include/daw/json/impl/daw_json_to_string.h:501:3: error: static_assert failed due to requirement 'std::is_convertible_v' "value must be convertible to specified type in class contract" static_assert( ^ _deps/daw_json_link-src/include/daw/json/impl/daw_json_to_string.h:996:10: note: in instantiation of function template specialization 'daw::json::json_details::to_string::name_code, double, daw::json::LiteralAsStringOpt::Never, daw::json::default_constructor, daw::json::JsonRangeCheck::Never, daw::json::JsonNullable::Never>, std::back_insert_iterator>, api::request::code>' requested here return to_string( ParseTag{ }, ^ _deps/daw_json_link-src/include/daw/json/impl/daw_json_to_string.h:506:8: error: no matching function for call to 'isnan' if( std::isnan( value ) ) { ^~~~~~~~~~ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:611:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'float' for 1st argument isnan(float __x) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:619:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'double' for 1st argument isnan(double __x) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:624:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'long double' for 1st argument isnan(long double __x) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:632:5: note: candidate template ignored: substitution failure [with _Tp = api::request::code]: no type named '__type' in '__gnu_cxx::__enable_if' isnan(_Tp __x) ^ In file included from ../main.cpp:2: In file included from _deps/daw_json_link-src/include/daw/json/daw_json_link.h:10: In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json.h:11: In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json_fwd.h:11: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_types_fwd.h:12: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_impl.h:16: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_serialize_impl.h:10: _deps/daw_json_link-src/include/daw/json/impl/daw_json_to_string.h:516:15: error: no matching function for call to 'isinf' } else if( std::isinf( value ) ) { ^~~~~~~~~~ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:584:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'float' for 1st argument isinf(float __x) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:592:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'double' for 1st argument isinf(double __x) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:597:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'long double' for 1st argument isinf(long double __x) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:605:5: note: candidate template ignored: substitution failure [with _Tp = api::request::code]: no type named '__type' in '__gnu_cxx::__enable_if' isinf(_Tp __x) ^ In file included from ../main.cpp:2: In file included from _deps/daw_json_link-src/include/daw/json/daw_json_link.h:10: In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json.h:11: In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json_fwd.h:11: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_types_fwd.h:12: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_impl.h:16: In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_serialize_impl.h:10: _deps/daw_json_link-src/include/daw/json/impl/daw_json_to_string.h:547:38: error: no matching function for call to 'to_string' it = utils::copy_to_iterator( it, to_string( value ) ); ^~~~~~~~~ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6597:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'int' for 1st argument to_string(int __val) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6608:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'unsigned int' for 1st argument to_string(unsigned __val) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6616:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'long' for 1st argument to_string(long __val) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6627:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'unsigned long' for 1st argument to_string(unsigned long __val) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6635:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'long long' for 1st argument to_string(long long __val) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/11/bits/basic_string.h:6647:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'unsigned long long' for 1st argument to_string(unsigned long long __val) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6658:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'float' for 1st argument to_string(float __val) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6667:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'double' for 1st argument to_string(double __val) ^ /bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6676:3: note: candidate function not viable: no known conversion from 'const api::request::code' to 'long double' for 1st argument to_string(long double __val) ^ _deps/daw_json_link-src/include/daw/json/impl/daw_json_to_string.h:77:35: note: candidate template ignored: could not match 'optional' against 'const api::request::code' [[nodiscard, maybe_unused]] auto to_string( std::optional const &v ) ^ 5 errors generated. ninja: build stopped: subcommand failed. Build finished with exit code 1 ```
0xBYTESHIFT commented 3 years ago

I tried different approach, but the results are not much better:

#include <iostream>
#include <daw/json/daw_json_link.h>
#include <magic_enum.hpp>

namespace api
{

    enum class code : int
    {
        OK = 0,
        ERROR
    };
    struct request
    {
        std::string type = "request";
        code c;
    };

    constexpr auto to_string(api::code c)
    {
        return magic_enum::enum_name(c);
    }
    constexpr auto from_string(daw::tag_t<api::code>, std::string_view sv) -> api::code
    {
        auto c = magic_enum::enum_cast<api::code>(sv);
        if (c.has_value())
        {
            return c.value();
        }
        throw std::runtime_error("unknown api::code");
    }
};

namespace daw::json
{
    template <>
    struct json_data_contract<api::request>
    {
        static constexpr char const name_type[] = "type";
        static constexpr char const name_code[] = "code";

        using type = json_member_list<
            json_string<name_type>,
            json_string<name_code, json_custom<no_name, api::code>>>;

        static inline auto to_json_data(const api::request &value)
        {
            return std::forward_as_tuple(
                value.type,
                value.c);
        }
    };
} // namespace daw::json

int main(int, char **)
{
    auto data = "{ \"type\":\"request\", \"code\":0 }";
    auto req = daw::json::from_json<api::request>(data);
    std::cout << daw::json::to_json(req) << "\n";
}
Errors ``` [main] Building folder: daw_json_example [build] Starting build [proc] Executing command: /usr/bin/cmake --build /home/eugene/gits/daw_json_example/build --config Debug --target all -j 14 -- [build] [1/2 50% :: 1.562] Building CXX object CMakeFiles/example.dir/main.cpp.o [build] FAILED: CMakeFiles/example.dir/main.cpp.o [build] /bin/clang++-11 -I_deps/daw_json_link-src/include -I_deps/daw_utf_range-src/include -I_deps/magic_enum-src/include -isystem _deps/daw_header_libraries-src/include -g -std=gnu++17 -MD -MT CMakeFiles/example.dir/main.cpp.o -MF CMakeFiles/example.dir/main.cpp.o.d -o CMakeFiles/example.dir/main.cpp.o -c ../main.cpp [build] In file included from ../main.cpp:2: [build] In file included from _deps/daw_json_link-src/include/daw/json/daw_json_link.h:12: [build] _deps/daw_json_link-src/include/daw/json/daw_json_link_types.h:375:3: error: static_assert failed due to requirement 'std::is_invocable_v, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, const char *, const char *>' [build] static_assert( [build] ^ [build] _deps/daw_json_link-src/include/daw/json/impl/daw_json_traits.h:194:3: note: in instantiation of template class 'daw::json::json_string<&daw::json::json_data_contract::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>' requested here [build] using json_type_t = typename T::i_am_a_json_type; [build] ^ [build] _deps/daw_header_libraries-src/include/daw/iterator/../cpp_17.h:157:40: note: in instantiation of template type alias 'json_type_t' requested here [build] struct detector>, Op, Args...> { [build] ^ [build] _deps/daw_header_libraries-src/include/daw/iterator/../cpp_17.h:164:2: note: during template argument deduction for class template partial specialization 'detector>, Op, Args...>' [with Default = daw::nonesuch, Op = json_type_t, Args = ::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>>] [build] using is_detected = [build] ^ [build] _deps/daw_header_libraries-src/include/daw/iterator/../cpp_17.h:164:2: note: in instantiation of template class 'daw::cpp_17_details::detector::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>>' requested here [build] _deps/daw_header_libraries-src/include/daw/iterator/../cpp_17.h:175:40: note: in instantiation of template type alias 'is_detected' requested here [build] inline constexpr bool is_detected_v = is_detected::value; [build] ^ [build] _deps/daw_json_link-src/include/daw/json/impl/daw_json_traits.h:197:49: note: in instantiation of variable template specialization 'daw::is_detected_v::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>>' requested here [build] inline constexpr bool is_a_json_type_v = daw::is_detected_v; [build] ^ [build] _deps/daw_json_link-src/include/daw/json/daw_json_link_types.h:30:34: note: in instantiation of variable template specialization 'daw::json::json_details::is_a_json_type_v::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>>' requested here [build] static_assert( ( json_details::is_a_json_type_v and ... ), [build] ^ [build] _deps/daw_json_link-src/include/daw/json/impl/daw_json_parse_value.h:449:19: note: in instantiation of template class 'daw::json::json_member_list::name_type, std::__cxx11::basic_string, daw::json::default_constructor>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>, daw::json::json_string<&daw::json::json_data_contract::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>>' requested here [build] auto result = json_data_contract_trait_t< [build] ^ [build] _deps/daw_json_link-src/include/daw/json/daw_from_json.h:42:24: note: in instantiation of function template specialization 'daw::json::json_details::parse_value, daw::json::JsonNullable::Never>, false, daw::json::BasicParsePolicy, daw::json::constexpr_exec_tag, false, daw::json::json_details::NoAllocator>>' requested here [build] return json_details::parse_value( [build] ^ [build] ../main.cpp:58:27: note: in instantiation of function template specialization 'daw::json::from_json, daw::json::constexpr_exec_tag, false, daw::json::json_details::NoAllocator>, false, api::request>' requested here [build] auto req = daw::json::from_json(data); [build] ^ [build] In file included from ../main.cpp:2: [build] In file included from _deps/daw_json_link-src/include/daw/json/daw_json_link.h:12: [build] _deps/daw_json_link-src/include/daw/json/daw_json_link_types.h:30:3: error: static_assert failed due to requirement 'json_details::is_a_json_type_v::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>>' "Only JSON Link mapping types can appear in a json_member_list(e.g. json_number, json_string...)" [build] static_assert( ( json_details::is_a_json_type_v and ... ), [build] ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [build] _deps/daw_json_link-src/include/daw/json/impl/daw_json_parse_value.h:449:19: note: in instantiation of template class 'daw::json::json_member_list::name_type, std::__cxx11::basic_string, daw::json::default_constructor>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>, daw::json::json_string<&daw::json::json_data_contract::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>>' requested here [build] auto result = json_data_contract_trait_t< [build] ^ [build] _deps/daw_json_link-src/include/daw/json/daw_from_json.h:42:24: note: in instantiation of function template specialization 'daw::json::json_details::parse_value, daw::json::JsonNullable::Never>, false, daw::json::BasicParsePolicy, daw::json::constexpr_exec_tag, false, daw::json::json_details::NoAllocator>>' requested here [build] return json_details::parse_value( [build] ^ [build] ../main.cpp:58:27: note: in instantiation of function template specialization 'daw::json::from_json, daw::json::constexpr_exec_tag, false, daw::json::json_details::NoAllocator>, false, api::request>' requested here [build] auto req = daw::json::from_json(data); [build] ^ [build] In file included from ../main.cpp:2: [build] In file included from _deps/daw_json_link-src/include/daw/json/daw_json_link.h:10: [build] In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json.h:11: [build] In file included from _deps/daw_json_link-src/include/daw/json/daw_from_json_fwd.h:11: [build] In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_types_fwd.h:12: [build] In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_link_impl.h:16: [build] In file included from _deps/daw_json_link-src/include/daw/json/impl/daw_json_serialize_impl.h:10: [build] _deps/daw_json_link-src/include/daw/json/impl/daw_json_to_string.h:847:51: error: no member named 'serialize' in 'daw::json::json_member_list::name_type, std::__cxx11::basic_string, daw::json::default_constructor>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>, daw::json::json_string<&daw::json::json_data_contract::name_code, daw::json::json_custom<&daw::json::no_name, api::code, daw::json::custom_from_converter_t, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>, daw::json::default_constructor, daw::json::custom_to_converter_t, daw::json::CustomJsonTypes::Either, daw::json::JsonNullable::Never>>, daw::json::JsonNullable::Never, daw::json::EightBitModes::AllowFull, daw::json::JsonNullable::Never>>' [build] return json_data_contract_trait_t::serialize( [build] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ [build] _deps/daw_json_link-src/include/daw/json/impl/daw_json_to_string.h:996:10: note: in instantiation of function template specialization 'daw::json::json_details::to_string, daw::json::JsonNullable::Never>, std::back_insert_iterator>, api::request>' requested here [build] return to_string( ParseTag{ }, [build] ^ [build] _deps/daw_json_link-src/include/daw/json/daw_to_json.h:34:23: note: in instantiation of function template specialization 'daw::json::json_details::member_to_string, daw::json::JsonNullable::Never>, std::back_insert_iterator>, api::request>' requested here [build] (void)json_details::member_to_string( [build] ^ [build] ../main.cpp:59:29: note: in instantiation of function template specialization 'daw::json::to_json, api::request, daw::json::json_class<&daw::json::no_name, api::request, daw::json::default_constructor, daw::json::JsonNullable::Never>>' requested here [build] std::cout << daw::json::to_json(req) << "\n"; [build] ^ [build] 3 errors generated. [build] ninja: build stopped: subcommand failed. [build] Build finished with exit code 1 ```
0xBYTESHIFT commented 3 years ago

Ok, I managed to do it with json_custom and universal enum adapter like that:

#include <iostream>
#include <daw/json/daw_json_link.h>
#include <magic_enum.hpp>

namespace api
{
    struct request
    {
        enum class code : int
        {
            OK = 0,
            ERROR
        };
        std::string type = "request";
        code c;
    };

};

template <class T>
struct CodeConverter
{
    auto operator()(std::string_view sv) const -> T
    {
        auto c = magic_enum::enum_cast<T>(sv);
        if (c.has_value())
        {
            return c.value();
        }
        throw std::runtime_error("unknown enum");
    }

    auto operator()(T c) const -> std::string_view
    {
        return magic_enum::enum_name(c);
    }
};

namespace daw::json
{
    template <>
    struct json_data_contract<api::request>
    {
        static constexpr char const name_type[] = "type";
        static constexpr char const name_code[] = "code";

        using code_t = api::request::code;
        using type = json_member_list<
            json_string<name_type>,
            json_custom<name_code, code_t, CodeConverter<code_t>, CodeConverter<code_t>>>;

        static inline auto to_json_data(const api::request &value)
        {
            return std::forward_as_tuple(
                value.type,
                value.c);
        }
    };
} // namespace daw::json

int main(int, char **)
{
    auto data = "{ \"type\":\"request\", \"code\":\"OK\" }";
    auto req = daw::json::from_json<api::request>(data);
    std::cout << daw::json::to_json(req) << "\n";
}
beached commented 3 years ago

First, for enum's you should specify the type in the mapping, json_number<name_code, api::request::code>

Also keep in mind is you are mapping the JSON members needed to construct your class, but are trying to construct a request with 2 elements. The error can be improved here and will be in future versions.

Because the type member is a static, it plays no part in requests construction.

Regarding encoding enum's : https://github.com/beached/daw_json_link/blob/release/cookbook/enums.md

Also, I suspect you will be doing a variant like pattern here, so this may come in handy too https://github.com/beached/daw_json_link/blob/release/cookbook/variant.md

There was a bug in enum classes with signed underlying types(that should have been default parsed but I generally have unsigned ones) that was missed in test(now tested) It will be in release once https://github.com/beached/daw_json_link/pull/229 is merged

beached commented 3 years ago

Sorry, I had a Sunday morning lack of coffee mishap. The PR is https://github.com/beached/daw_json_link/pull/230

beached commented 3 years ago

As of https://github.com/beached/daw_json_link/releases/tag/v2.9.3 the fixes are in release