#include "ikarus/values/value.h" #include #include #include // required for header-only inclusion #include #include #include #include #include #include IkarusValue::IkarusValue(Data data): data(data) {} cppbase::Result IkarusValue::from_json(boost::json::value const& json) { if (auto const * obj = json.if_object(); obj == nullptr) { return cppbase::err(FromJsonError{}); } else { boost::int64_t const * type = nullptr; boost::json::value const * data = nullptr; if (auto const * type_value = obj->if_contains("type"); type_value == nullptr) { return cppbase::err(FromJsonError{}); } else if (type = type_value->if_int64(); type == nullptr) { return cppbase::err(FromJsonError{}); } if (data = obj->if_contains("data"); data == nullptr) { return cppbase::err(FromJsonError{}); } auto create_value = [data]() -> cppbase::Result { T * ret = nullptr; if (data->is_null()) { ret = new T{}; ret->data = boost::variant2::monostate{}; } else { auto res = boost::json::try_value_to< boost::container::small_vector>(*data); if (res.has_error()) { return cppbase::err(FromJsonError{}); } ret = new T{}; ret->data = std::move(res.value()); } return cppbase::ok(ret); }; switch (*type) { case IkarusPropertyType_Toggle: { return create_value.operator()(); } case IkarusPropertyType_Number: { return create_value.operator()(); } case IkarusPropertyType_Text: { return create_value.operator()(); } default: { return cppbase::err(FromJsonError{}); } } } } boost::json::value IkarusValue::to_json() const { auto type = boost::variant2::visit( boost::make_overloaded_function( []([[maybe_unused]] IkarusToggleValue const * value) { return IkarusPropertyType_Toggle; }, []([[maybe_unused]] IkarusNumberValue const * value) { return IkarusPropertyType_Number; }, []([[maybe_unused]] IkarusTextValue const * value) { return IkarusPropertyType_Text; } ), data ); auto data_json = boost::variant2::visit( [](T const * value) -> boost::json::value { return boost::variant2::visit( boost::make_overloaded_function( []([[maybe_unused]] boost::variant2::monostate const& data) -> boost::json::value { return nullptr; }, [](auto const& data) -> boost::json::value { return boost::json::value_from(data); } ), value->data ); }, data ); return { {"type", type}, {"data", data_json} }; } void ikarus_value_visit( IkarusValue * value, void (*toggle_visitor)(IkarusToggleValue *, void *), void (*number_visitor)(IkarusNumberValue *, void *), void (*text_visitor)(IkarusTextValue *, void *), void * data ) { boost::variant2::visit( boost::make_overloaded_function( [toggle_visitor, data](IkarusToggleValue * toggle_value) { toggle_visitor(toggle_value, data); }, [number_visitor, data](IkarusNumberValue * number_value) { number_visitor(number_value, data); }, [text_visitor, data](IkarusTextValue * text_value) { text_visitor(text_value, data); } ), value->data ); } void ikarus_value_visit_const( IkarusValue const * value, void (*toggle_visitor)(IkarusToggleValue const *, void *), void (*number_visitor)(IkarusNumberValue const *, void *), void (*text_visitor)(IkarusTextValue const *, void *), void * data ) { boost::variant2::visit( boost::make_overloaded_function( [toggle_visitor, data](IkarusToggleValue const * toggle_value) { toggle_visitor(toggle_value, data); }, [number_visitor, data](IkarusNumberValue const * number_value) { number_visitor(number_value, data); }, [text_visitor, data](IkarusTextValue const * text_value) { text_visitor(text_value, data); } ), value->data ); }