#pragma once #include #include #include #include #include struct IkarusValue { public: using Data = boost::variant2::variant; constexpr static auto SMALL_VEC_VALUE_SIZE = 8; public: explicit IkarusValue(Data data); IkarusValue(IkarusValue const &) = default; IkarusValue(IkarusValue &&) noexcept = default; IkarusValue & operator=(IkarusValue const &) = default; IkarusValue & operator=(IkarusValue &&) noexcept = default; virtual ~IkarusValue() = default; public: struct FromJsonError {}; [[nodiscard]] static cppbase::Result from_json(boost::json::value json); [[nodiscard]] boost::json::value to_json() const; public: Data data; }; template<> struct fmt::formatter { template constexpr static auto parse(FormatParseContext & ctx) { return ctx.end(); } constexpr static auto format([[maybe_unused]]IkarusValue::FromJsonError const & error, fmt::format_context & ctx) { return fmt::format_to(ctx.out(), "unable to parse ikarus value JSON"); } }; template IkarusValue * fetch_value_from_db(IkarusProject * project, IkarusErrorData * error_out, std::string_view query, Args &&... args) { IKARUS_VTRYRV_OR_FAIL( auto const value_str, nullptr, "unable to fetch entity property value from database: {}", IkarusErrorInfo_Database_QueryFailed, project->db->query_one(query, std::forward(args)...) ); boost::json::error_code ec{}; boost::json::value json_value = boost::json::parse(value_str, ec); if (ec) { IKARUS_SET_ERROR(fmt::format("invalid json is stored in database: {}", ec.message()), IkarusErrorInfo_Database_InvalidState); return nullptr; } IKARUS_VTRYRV_OR_FAIL( auto const ret, nullptr, "unable to fetch entity property value: {}", IkarusErrorInfo_LibIkarus_CannotPerformOperation, IkarusValue::from_json(std::move(json_value)) ); return ret; }