fixup compiler errors & finalize json (de-)serialization for values
Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
parent
7f24d3d064
commit
e22bfba991
13 changed files with 116 additions and 58 deletions
|
|
@ -91,8 +91,9 @@ IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * p
|
|||
|
||||
auto * ctx = property->get_project()->get_function_context();
|
||||
|
||||
VTRY(
|
||||
VTRYRV(
|
||||
auto const source,
|
||||
nullptr,
|
||||
property->get_project()
|
||||
->get_db()
|
||||
->query_one<int>("SELECT `source` FROM `properties` WHERE `id` = ?", property->get_id())
|
||||
|
|
@ -129,8 +130,9 @@ IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property)
|
|||
|
||||
auto * ctx = property->get_project()->get_function_context();
|
||||
|
||||
VTRY(
|
||||
VTRYRV(
|
||||
auto const value,
|
||||
nullptr,
|
||||
property->get_project()
|
||||
->get_db()
|
||||
->query_one<int>("SELECT `default_value` FROM `properties` WHERE `id` = ?", property->get_id())
|
||||
|
|
@ -144,7 +146,7 @@ IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property)
|
|||
})
|
||||
);
|
||||
|
||||
return new IkarusValue(property->get_project(), value);
|
||||
return IkarusValue::from_json(value).unwrap_value_or(nullptr);
|
||||
}
|
||||
|
||||
void ikarus_property_visit(
|
||||
|
|
|
|||
3
src/redirect/json.hpp
Normal file
3
src/redirect/json.hpp
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/json/src.hpp>
|
||||
|
|
@ -12,7 +12,7 @@ IkarusNumberValue * ikarus_number_value_create() {
|
|||
return new IkarusNumberValue{};
|
||||
}
|
||||
|
||||
long double const * ikarus_number_value_get(IkarusNumberValue * value, size_t idx) {
|
||||
double const * ikarus_number_value_get(IkarusNumberValue * value, size_t idx) {
|
||||
return ikarus_value_base_get(value, idx);
|
||||
}
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ size_t ikarus_number_value_get_size(IkarusNumberValue const * value) {
|
|||
return ikarus_value_base_get_size(value);
|
||||
}
|
||||
|
||||
void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, long double new_data) {
|
||||
void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, double new_data) {
|
||||
return ikarus_value_base_set(value, idx, new_data);
|
||||
}
|
||||
|
||||
|
|
@ -45,12 +45,7 @@ void ikarus_number_value_set_undefined(IkarusNumberValue * value, bool undefined
|
|||
}
|
||||
|
||||
char const * ikarus_number_value_to_string(IkarusNumberValue const * value) {
|
||||
return boost::variant2::visit(
|
||||
boost::make_overloaded_function(
|
||||
[](boost::variant2::monostate const&) { return nullptr; }, [](auto const& data) { return fmt::join(data, ", "); }
|
||||
),
|
||||
value->data
|
||||
);
|
||||
return ikarus_value_base_to_string(value, [](auto const& value) { return value; });
|
||||
}
|
||||
|
||||
bool ikarus_number_value_is_equal(IkarusNumberValue const * lhs, IkarusNumberValue const * rhs) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <boost/variant2.hpp>
|
||||
|
||||
#include <values/value.hpp>
|
||||
|
||||
struct IkarusNumberValue final : IkarusValue {
|
||||
public:
|
||||
using data_type = long double;
|
||||
using data_type = double;
|
||||
|
||||
public:
|
||||
explicit IkarusNumberValue();
|
||||
|
|
@ -21,7 +21,6 @@ public:
|
|||
~IkarusNumberValue() override = default;
|
||||
|
||||
public:
|
||||
boost::variant2::
|
||||
variant<boost::variant2::monostate, boost::container::small_vector<data_type, SMALL_VEC_VALUE_SIZE>>
|
||||
data{};
|
||||
boost::variant2::variant<boost::variant2::monostate, boost::container::small_vector<data_type, SMALL_VEC_VALUE_SIZE>> data{
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "ikarus/values/text_value.h"
|
||||
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/functional/overloaded_function.hpp>
|
||||
|
||||
#include <values/text_value.hpp>
|
||||
|
|
@ -45,12 +46,7 @@ void ikarus_text_value_set_undefined(IkarusTextValue * value, bool undefined) {
|
|||
}
|
||||
|
||||
char const * ikarus_text_value_to_string(IkarusTextValue const * value) {
|
||||
return boost::variant2::visit(
|
||||
boost::make_overloaded_function(
|
||||
[](boost::variant2::monostate const&) { return nullptr; }, [](auto const& data) { return fmt::join(data, ", "); }
|
||||
),
|
||||
value->data
|
||||
);
|
||||
return ikarus_value_base_to_string(value, [](auto const& value) { return value; });
|
||||
}
|
||||
|
||||
bool ikarus_text_value_is_equal(IkarusTextValue const * lhs, IkarusTextValue const * rhs) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#include <values/value.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -46,17 +46,7 @@ void ikarus_toggle_value_set_undefined(IkarusToggleValue * value, bool undefined
|
|||
}
|
||||
|
||||
char const * ikarus_toggle_value_to_string(IkarusToggleValue const * value) {
|
||||
return boost::variant2::visit(
|
||||
boost::make_overloaded_function(
|
||||
[](boost::variant2::monostate const&) { return nullptr; },
|
||||
[](auto const& data) {
|
||||
return fmt::join(
|
||||
data | boost::adaptors::transformed([](auto const& bool_value) { return bool_value ? "✓" : "✗"; }), ", "
|
||||
);
|
||||
}
|
||||
),
|
||||
value->data
|
||||
);
|
||||
return ikarus_value_base_to_string(value, [](auto const& value) { return value ? "✓" : "✗"; });
|
||||
}
|
||||
|
||||
bool ikarus_toggle_value_is_equal(IkarusToggleValue const * lhs, IkarusToggleValue const * rhs) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#include <values/value.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <boost/functional/overloaded_function.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <fmt/format.h>
|
||||
// required for header-only inclusion
|
||||
#include <boost/json/src.hpp>
|
||||
|
||||
#include <ikarus/objects/properties/property_type.h>
|
||||
|
||||
|
|
@ -17,7 +18,7 @@
|
|||
IkarusValue::IkarusValue(Data data):
|
||||
data(data) {}
|
||||
|
||||
cppbase::Result<IkarusValue, IkarusValue::FromJsonError> IkarusValue::from_json(boost::json::value const& json) {
|
||||
cppbase::Result<IkarusValue *, IkarusValue::FromJsonError> IkarusValue::from_json(boost::json::value const& json) {
|
||||
if (auto const * obj = json.if_object(); obj == nullptr) {
|
||||
return cppbase::err(FromJsonError{});
|
||||
} else {
|
||||
|
|
@ -35,15 +36,23 @@ cppbase::Result<IkarusValue, IkarusValue::FromJsonError> IkarusValue::from_json(
|
|||
}
|
||||
|
||||
auto create_value = [data]<typename T>() -> cppbase::Result<IkarusValue *, FromJsonError> {
|
||||
auto * ret = new T{};
|
||||
auto res = boost::json::try_value_to<boost::container::vector<typename T::data_type>>(*data);
|
||||
T * ret = nullptr;
|
||||
|
||||
if (res.has_error()) {
|
||||
return cppbase::err(FromJsonError{});
|
||||
if (data->is_null()) {
|
||||
ret = new T{};
|
||||
ret->data = boost::variant2::monostate{};
|
||||
} else {
|
||||
auto res = boost::json::try_value_to<
|
||||
boost::container::small_vector<typename T::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE>>(*data);
|
||||
|
||||
if (res.has_error()) {
|
||||
return cppbase::err(FromJsonError{});
|
||||
}
|
||||
|
||||
ret = new T{};
|
||||
ret->data = std::move(res.value());
|
||||
}
|
||||
|
||||
ret->data = std::move(res.value());
|
||||
|
||||
return cppbase::ok(ret);
|
||||
};
|
||||
|
||||
|
|
@ -74,7 +83,18 @@ boost::json::value IkarusValue::to_json() const {
|
|||
data
|
||||
);
|
||||
|
||||
auto data_json = boost::variant2::visit([](auto const * value) { return boost::json::value_from(value->data); }, data);
|
||||
auto data_json = boost::variant2::visit(
|
||||
[]<typename T>(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},
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
struct IkarusValue {
|
||||
public:
|
||||
using Data = boost::variant2::variant<struct IkarusToggleValue *, struct IkarusNumberValue *, struct IkarusTextValue *>;
|
||||
constexpr auto SMALL_VEC_VALUE_SIZE = 8;
|
||||
constexpr static auto SMALL_VEC_VALUE_SIZE = 8;
|
||||
|
||||
public:
|
||||
explicit IkarusValue(Data data);
|
||||
|
|
@ -24,7 +24,7 @@ public:
|
|||
public:
|
||||
struct FromJsonError {};
|
||||
|
||||
[[nodiscard]] static cppbase::Result<IkarusValue, FromJsonError> from_json(boost::json::value const& json);
|
||||
[[nodiscard]] static cppbase::Result<IkarusValue *, FromJsonError> from_json(boost::json::value const& json);
|
||||
[[nodiscard]] boost::json::value to_json() const;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include <ranges>
|
||||
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <boost/functional/overloaded_function.hpp>
|
||||
|
||||
template<typename V>
|
||||
typename V::data_type const * ikarus_value_base_get(V * value, size_t idx) {
|
||||
if (auto * data = value->data.template get_if<std::vector<typename V::data_type>>(); data != nullptr) {
|
||||
if (auto * data =
|
||||
boost::variant2::get_if<boost::container::small_vector<typename V::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE>>(
|
||||
&value->data
|
||||
);
|
||||
data != nullptr) {
|
||||
return &(*data)[idx];
|
||||
}
|
||||
|
||||
|
|
@ -11,7 +22,11 @@ typename V::data_type const * ikarus_value_base_get(V * value, size_t idx) {
|
|||
|
||||
template<typename V>
|
||||
size_t ikarus_value_base_get_size(V const * value) {
|
||||
if (auto * data = value->data.template get_if<std::vector<typename V::data_type>>(); data != nullptr) {
|
||||
if (auto * data =
|
||||
boost::variant2::get_if<boost::container::small_vector<typename V::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE>>(
|
||||
&value->data
|
||||
);
|
||||
data != nullptr) {
|
||||
return data->size();
|
||||
}
|
||||
|
||||
|
|
@ -20,28 +35,44 @@ size_t ikarus_value_base_get_size(V const * value) {
|
|||
|
||||
template<typename V>
|
||||
void ikarus_value_base_set(V * value, size_t idx, typename V::data_type new_data) {
|
||||
if (auto * data = value->data.template get_if<std::vector<typename V::data_type>>(); data != nullptr) {
|
||||
if (auto * data =
|
||||
boost::variant2::get_if<boost::container::small_vector<typename V::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE>>(
|
||||
&value->data
|
||||
);
|
||||
data != nullptr) {
|
||||
(*data)[idx] = new_data;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
void ikarus_value_base_remove(V * value, size_t idx) {
|
||||
if (auto * data = value->data.template get_if<std::vector<typename V::data_type>>(); data != nullptr) {
|
||||
if (auto * data =
|
||||
boost::variant2::get_if<boost::container::small_vector<typename V::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE>>(
|
||||
&value->data
|
||||
);
|
||||
data != nullptr) {
|
||||
data->erase(data->begin() + idx);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
void ikarus_value_base_insert(V * value, size_t idx, typename V::data_type new_data) {
|
||||
if (auto * data = value->data.template get_if<std::vector<typename V::data_type>>(); data != nullptr) {
|
||||
if (auto * data =
|
||||
boost::variant2::get_if<boost::container::small_vector<typename V::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE>>(
|
||||
&value->data
|
||||
);
|
||||
data != nullptr) {
|
||||
data->insert(data->begin() + idx, new_data);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
void ikarus_value_base_clear(V * value) {
|
||||
if (auto * data = value->data.template get_if<std::vector<typename V::data_type>>(); data != nullptr) {
|
||||
if (auto * data =
|
||||
boost::variant2::get_if<boost::container::small_vector<typename V::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE>>(
|
||||
&value->data
|
||||
);
|
||||
data != nullptr) {
|
||||
data->clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -56,10 +87,32 @@ void ikarus_value_base_set_undefined(V * value, bool undefined) {
|
|||
if (undefined) {
|
||||
value->data = boost::variant2::monostate{};
|
||||
} else {
|
||||
value->data = typename V::data_type{};
|
||||
value->data = boost::container::small_vector<typename V::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE>{};
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, std::invocable<typename V::data_type> F>
|
||||
char const * ikarus_value_base_to_string(V const * value, F transformer) {
|
||||
return boost::variant2::visit(
|
||||
boost::make_overloaded_function(
|
||||
[](boost::variant2::monostate const&) -> char const * { return nullptr; },
|
||||
[&transformer](boost::container::small_vector<typename V::data_type, IkarusValue::SMALL_VEC_VALUE_SIZE> const& data
|
||||
) -> char const * {
|
||||
auto buffer = fmt::memory_buffer{};
|
||||
|
||||
fmt::format_to(
|
||||
std::back_inserter(buffer),
|
||||
"{}",
|
||||
fmt::join(data | std::views::transform(std::forward<F>(transformer)), ", ")
|
||||
);
|
||||
|
||||
return buffer.data();
|
||||
}
|
||||
),
|
||||
value->data
|
||||
);
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
bool ikarus_value_base_is_equal(V const * lhs, V const * rhs) {
|
||||
return lhs->data == rhs->data;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue