diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 0769662868..6e2ab7285f 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -48,7 +48,7 @@ jobs: uses: lukka/run-vcpkg@v11 with: vcpkgDirectory: '/opt/vcpkg' - vcpkgGitCommitId: 'a34c873a9717a888f58dc05268dea15592c2f0ff' + vcpkgGitCommitId: '66a252f70eebdd744c02d7ab8c1cc6fe123c70ee' vcpkgJsonGlob: 'vcpkg.json' - name: Run CMake consuming CMakePreset.json and vcpkg.json by mean of vcpkg. diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5354759509..e9c08a1a11 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,7 +20,7 @@ jobs: uses: lukka/run-vcpkg@v11 with: vcpkgDirectory: '/opt/vcpkg' - vcpkgGitCommitId: 'a34c873a9717a888f58dc05268dea15592c2f0ff' + vcpkgGitCommitId: '66a252f70eebdd744c02d7ab8c1cc6fe123c70ee' vcpkgJsonGlob: 'vcpkg.json' - name: Build diff --git a/.github/workflows/ubuntu-packaging.yml b/.github/workflows/ubuntu-packaging.yml index 2a6f4dcaeb..8026856b27 100644 --- a/.github/workflows/ubuntu-packaging.yml +++ b/.github/workflows/ubuntu-packaging.yml @@ -46,7 +46,7 @@ jobs: uses: lukka/run-vcpkg@v11 with: vcpkgDirectory: '/opt/vcpkg' - vcpkgGitCommitId: 'a34c873a9717a888f58dc05268dea15592c2f0ff' + vcpkgGitCommitId: '66a252f70eebdd744c02d7ab8c1cc6fe123c70ee' vcpkgJsonGlob: 'vcpkg.json' - name: Run CMake consuming CMakePreset.json and vcpkg.json by mean of vcpkg. diff --git a/examples/test_rig/main.cpp b/examples/test_rig/main.cpp index 6c0d32e005..21e4c53d57 100644 --- a/examples/test_rig/main.cpp +++ b/examples/test_rig/main.cpp @@ -27,12 +27,12 @@ struct glz::meta { "servo_cycle", &config_struct::servo_cycle, tfc::json::schema{ .description = "Duration between moving the servo", - .default_value = 1000, - .minimum = 20, - .maximum = 5000 }, + .defaultValue = 1000UL, + .minimum = 20UL, + .maximum = 5000UL }, "count", &config_struct::count, - tfc::json::schema{ .description = "Servo wink count", .default_value = 10, .minimum = 1, .maximum = 180 }) }; + tfc::json::schema{ .description = "Servo wink count", .defaultValue = 10UL, .minimum = 1UL, .maximum = 180UL }) }; }; struct app { diff --git a/exes/ethercat/inc/public/tfc/ec/config/bus.hpp b/exes/ethercat/inc/public/tfc/ec/config/bus.hpp index e0136ec605..ad1ffbf184 100644 --- a/exes/ethercat/inc/public/tfc/ec/config/bus.hpp +++ b/exes/ethercat/inc/public/tfc/ec/config/bus.hpp @@ -25,15 +25,16 @@ struct network_interface { } // namespace tfc::ec::config template <> -struct tfc::json::detail::to_json_schema { +struct glz::detail::to_json_schema { template static void op(auto& s, auto&) noexcept { - s.oneOf = std::vector{}; - - for (auto const& interface : ec::common::get_interfaces()) { - s.oneOf->emplace_back(tfc::json::detail::schematic{ - .attributes{ tfc::json::schema{ .title = interface, .description = interface, .constant = interface } } }); - } + s.oneOf = std::vector{}; + // fix in https://github.com/Skaginn3x/framework/issues/555 + // attributes was added initially + // for (auto const& interface : tfc::ec::common::get_interfaces()) { + // s.oneOf->emplace_back(glz::detail::schematic{ + // .attributes{ tfc::json::schema{ .title = interface, .description = interface, .constant = interface } } }); + // } } }; diff --git a/exes/ethercat/inc/public/tfc/ec/devices/eilersen/4x60a.hpp b/exes/ethercat/inc/public/tfc/ec/devices/eilersen/4x60a.hpp index 3ccbba58b6..659e4c0319 100644 --- a/exes/ethercat/inc/public/tfc/ec/devices/eilersen/4x60a.hpp +++ b/exes/ethercat/inc/public/tfc/ec/devices/eilersen/4x60a.hpp @@ -177,7 +177,7 @@ struct meta { static constexpr std::string_view name{ "4x60a::calibration_zero" }; // clang-format off static constexpr auto value{ glz::object( - "signal_read", &type::read, tfc::json::schema{ .description = "The read value of the calibration zero", .read_only = true }, + "signal_read", &type::read, tfc::json::schema{ .description = "The read value of the calibration zero", .readOnly = true }, "do_calibrate_zero", &type::do_calibrate, "Set to true to calibrate the zero" ) }; // clang-format on @@ -189,8 +189,8 @@ struct meta { static constexpr std::string_view name{ "4x60a::calibration_weight" }; // clang-format off static constexpr auto value{ glz::object( - "signal_read", &type::read, tfc::json::schema{ .description="The actual value signal from load cell/cells of the calibration weight", .read_only = true }, - "weight", &type::weight, tfc::json::schema{ .description = "Calibration weight", .default_value = 1UL }, + "signal_read", &type::read, tfc::json::schema{ .description="The actual value signal from load cell/cells of the calibration weight", .readOnly = true }, + "weight", &type::weight, tfc::json::schema{ .description = "Calibration weight", .defaultValue = 1UL }, "do_calibrate_with_load", &type::do_calibrate, "Set to true to calibrate the weight" ) }; // clang-format on @@ -215,7 +215,7 @@ struct meta> { "cell/cells", &type::this_cells, "The cells to use for this calibration.", "group_name", &type::group_name, tfc::json::schema{ .description= "The name of this calibration group, used for naming IPC signal. Requires restart of the process.", - .min_length = 3, .max_length = 30, .pattern = "^[a-zA-Z0-9_]+$" } + .minLength = 3, .maxLength = 30, .pattern = "^[a-zA-Z0-9_]+$" } ) }; // clang-format on }; @@ -239,7 +239,7 @@ struct meta { static constexpr std::string_view name{ "Sealed Calibration Config" }; static constexpr auto value{ glz::object("calibration", &type::calibration_v, - tfc::json::schema{ .read_only = true }, + tfc::json::schema{ .readOnly = true }, "sealed", &type::sealed, tfc::json::schema{ .constant = true }) }; diff --git a/exes/ethercat/inc/public/tfc/ec/devices/util.hpp b/exes/ethercat/inc/public/tfc/ec/devices/util.hpp index c7ccefc86f..fe224a32a1 100644 --- a/exes/ethercat/inc/public/tfc/ec/devices/util.hpp +++ b/exes/ethercat/inc/public/tfc/ec/devices/util.hpp @@ -87,14 +87,13 @@ struct glz::meta; }; -namespace tfc::json::detail { template -struct to_json_schema> { +struct glz::detail::to_json_schema> { using setting = tfc::ec::util::setting; static constexpr auto name_view{ name_value.view() }; static constexpr auto description{ tfc::stx::string_view_join_v< // @@ -107,10 +106,10 @@ struct to_json_schema }; template static void op(auto& schema, auto& defs) { - schema.attributes.title = desc; - schema.attributes.description = description; + // fix in https://github.com/Skaginn3x/framework/issues/555 + // attributes was added initially + // schema.attributes.title = desc; + // schema.attributes.description = description; to_json_schema::template op(schema, defs); } }; - -} // namespace tfc::json::detail diff --git a/exes/mqtt-bridge/inc/config/bridge.hpp b/exes/mqtt-bridge/inc/config/bridge.hpp index 53f6ee43e7..a62b0546bf 100644 --- a/exes/mqtt-bridge/inc/config/bridge.hpp +++ b/exes/mqtt-bridge/inc/config/bridge.hpp @@ -69,16 +69,18 @@ struct glz::meta { }; template <> -struct tfc::json::detail::to_json_schema { +struct glz::detail::to_json_schema { template static void op(auto& s, auto&) noexcept { if (!s.oneOf.has_value()) { s.oneOf = std::vector{}; } - for (auto const& signal : global::get_signals()) { - s.oneOf.value().push_back(schematic{ - .attributes{ schema{ .title = signal.name, .description = signal.description, .constant = signal.name } } }); - } + // fix in https://github.com/Skaginn3x/framework/issues/555 + // attributes was added initially + // for (auto const& signal : tfc::global::get_signals()) { + // s.oneOf.value().push_back(schematic{ + // .attributes{ schema{ .title = signal.name, .description = signal.description, .constant = signal.name } } }); + // } } }; diff --git a/libs/ipc/testing/tests/filter_test.cpp b/libs/ipc/testing/tests/filter_test.cpp index 8cdeba924b..f95d018e4a 100644 --- a/libs/ipc/testing/tests/filter_test.cpp +++ b/libs/ipc/testing/tests/filter_test.cpp @@ -167,7 +167,7 @@ auto main(int, char**) -> int { expect(generic_config.has_value() >> fatal); generic_config->at("time_on") = 1; // reduce time to only 1 millisecond generic_config->at("time_off") = 1; - expect(!config.from_string(glz::write_json(generic_config)) >> fatal); + expect(!config.from_string(glz::write_json(generic_config.value())) >> fatal); expect(config->time_on == 1ms); expect(config->time_off == 1ms); diff --git a/libs/motor/inc/public/tfc/motor.hpp b/libs/motor/inc/public/tfc/motor.hpp index f9de88aa94..55df6bfe2d 100644 --- a/libs/motor/inc/public/tfc/motor.hpp +++ b/libs/motor/inc/public/tfc/motor.hpp @@ -581,5 +581,5 @@ template <> struct glz::meta { using self = tfc::motor::details::not_used; static constexpr std::string_view name{ "Not used" }; - static constexpr auto value{ glz::object("value", &self::value, tfc::json::schema{ .read_only = true }) }; + static constexpr auto value{ glz::object("value", &self::value, tfc::json::schema{ .readOnly = true }) }; }; diff --git a/libs/motor/inc/public/tfc/motor/details/positioner_impl.hpp b/libs/motor/inc/public/tfc/motor/details/positioner_impl.hpp index cb3ca2f83c..4284667f5c 100644 --- a/libs/motor/inc/public/tfc/motor/details/positioner_impl.hpp +++ b/libs/motor/inc/public/tfc/motor/details/positioner_impl.hpp @@ -333,12 +333,12 @@ struct glz::meta> { .description = "Displacement per increment\n" "Mode: tachometer, displacement per pulse or distance between two teeths\n" "Mode: encoder, displacement per edge, distance between two teeths divided by 4", - .default_value = self::inch.numerical_value_ref_in(reference), + .defaultValue = self::inch.numerical_value_ref_in(reference), .minimum = 1UL, }, "standard_deviation_threshold", &self::standard_deviation_threshold, tfc::json::schema{ .description = "Standard deviation between increments, used to determine if signal is stable", - .default_value = 100UL, + .defaultValue = 100UL, .minimum = 1UL, } ) @@ -364,7 +364,7 @@ struct glz::meta> { glz::object( "velocity_at_50Hz", &self::velocity_at_50Hz, tfc::json::schema{ .description = "Velocity at 50Hz", - .default_value = 0UL, + .defaultValue = 0UL, } ) }; diff --git a/libs/stx/inc/public/tfc/stx/glaze_meta.hpp b/libs/stx/inc/public/tfc/stx/glaze_meta.hpp index 872213654b..5ff1e3de59 100644 --- a/libs/stx/inc/public/tfc/stx/glaze_meta.hpp +++ b/libs/stx/inc/public/tfc/stx/glaze_meta.hpp @@ -113,20 +113,6 @@ struct duration_hack { }; } // namespace tfc::detail -template -struct glz::meta> { - static constexpr std::string_view prefix{ "std::expected<" }; - static constexpr std::string_view postfix{ ">" }; - static constexpr std::string_view delimiter{ ", " }; - static constexpr std::string_view name{ - tfc::stx::string_view_join_v, delimiter, name_v, postfix> - }; - static constexpr auto value{ [](auto&& self) -> auto& { - // todo this does not support error case - return self.value(); - } }; -}; - template struct glz::meta> { using type = std::ratio; @@ -142,7 +128,7 @@ struct glz::meta> { static constexpr std::string_view postfix{ ">" }; static constexpr std::string_view separator{ "," }; static constexpr auto name{ - tfc::stx::string_view_join_v, separator, glz::name_v, postfix> + tfc::stx::string_view_join_v, separator, glz::name_v, postfix> }; }; @@ -152,7 +138,7 @@ struct glz::meta> { static constexpr std::string_view postfix{ ">" }; static constexpr std::string_view separator{ "," }; static constexpr auto name{ - tfc::stx::string_view_join_v, separator, glz::name_v, postfix> + tfc::stx::string_view_join_v, separator, glz::name_v, postfix> }; }; @@ -167,7 +153,7 @@ struct glz::meta> { static constexpr std::string_view postfix{ ">" }; static constexpr std::string_view separator{ "," }; static constexpr auto name{ - tfc::stx::string_view_join_v, separator, glz::name_v, postfix> + tfc::stx::string_view_join_v, separator, glz::name_v, postfix> }; }; @@ -270,8 +256,9 @@ template struct to_json_schema> { template static void op(auto& schema, auto&) { - using enum tfc::json::defined_formats; - schema.attributes.format = datetime; + // fix in https://github.com/Skaginn3x/framework/issues/555 + // using enum tfc::json::defined_formats; + // schema.attributes.format = datetime; schema.type = { "string" }; } }; @@ -286,13 +273,14 @@ struct to_json_schema> { template static void op(auto& schema, auto& defs) { - auto& data = schema.attributes.tfc_metadata; - if (!data.has_value()) { - data = tfc::json::schema_meta{}; - } - data->unit = schema_meta::unit_meta{ .unit_ascii = unit, .unit_unicode = unit }; - data->dimension = "time"; - data->ratio = tfc::json::schema_meta::ratio_impl{ .numerator = period_t::num, .denominator = period_t::den }; + // fix in https://github.com/Skaginn3x/framework/issues/555 + // auto& data = schema.attributes.tfc_metadata; + // if (!data.has_value()) { + // data = tfc::json::schema_meta{}; + // } + // data->unit = schema_meta::unit_meta{ .unit_ascii = unit, .unit_unicode = unit }; + // data->dimension = "time"; + // data->ratio = tfc::json::schema_meta::ratio_impl{ .numerator = period_t::num, .denominator = period_t::den }; to_json_schema::template op(schema, defs); } }; @@ -301,11 +289,12 @@ template struct to_json_schema> { template static void op(auto& schema, auto& defs) { - auto& data = schema.attributes.tfc_metadata; - if (!data.has_value()) { - data = tfc::json::schema_meta{}; - } - data->required = false; + // fix in https://github.com/Skaginn3x/framework/issues/555 + // auto& data = schema.attributes.tfc_metadata; + // if (!data.has_value()) { + // data = tfc::json::schema_meta{}; + // } + // data->required = false; to_json_schema::template op(schema, defs); } }; diff --git a/libs/stx/inc/public/tfc/utils/json_schema.hpp b/libs/stx/inc/public/tfc/utils/json_schema.hpp index 1c29b8147a..8ca041bd6d 100644 --- a/libs/stx/inc/public/tfc/utils/json_schema.hpp +++ b/libs/stx/inc/public/tfc/utils/json_schema.hpp @@ -12,521 +12,24 @@ #include namespace tfc::json { -struct schema_meta final { - struct ratio_impl { - std::uint64_t numerator{}; - std::uint64_t denominator{}; - struct glaze { - // clang-format off - static constexpr auto value{ glz::object( - "numerator", &ratio_impl::numerator, - "denominator", &ratio_impl::denominator - ) }; - // clang-format on - }; - }; - struct unit_meta final { - std::string_view unit_ascii{}; - std::string_view unit_unicode{}; - struct glaze { - // clang-format off - static constexpr auto value{ glz::object( - "unit_ascii", &unit_meta::unit_ascii, - "unit_unicode", &unit_meta::unit_unicode - ) }; - // clang-format on - }; - }; - bool required{ true }; - std::optional unit{}; - std::optional dimension{}; - std::optional ratio{}; - struct glaze { - using type = schema_meta; - // clang-format off - static constexpr auto value{ glz::object( - "unit", &type::unit, - "dimension", &type::dimension, - "ratio", &type::ratio, - "required", &type::required - ) }; - // clang-format on - }; -}; -enum struct defined_formats : std::uint8_t { - datetime, - date, - time, - duration, - email, - idn_email, - hostname, - idn_hostname, - ipv4, - ipv6, - uri, - uri_reference, - iri, - iri_reference, - uuid, - uri_template, - json_pointer, - relative_json_pointer, - regex -}; - -struct schema { - std::string_view ref{}; - using schema_number = std::optional>; - using schema_any = std::variant; - // meta data keywords, ref: https://www.learnjsonschema.com/2020-12/meta-data/ - std::optional title{}; - std::optional description{}; - std::optional default_value{}; - std::optional deprecated{}; - // std vector requires exit destructor & global constructor - // std::optional> examples{}; - std::optional read_only{}; - std::optional write_only{}; - // hereafter validation keywords, ref: https://www.learnjsonschema.com/2020-12/validation/ - std::optional constant{}; - // string only keywords - std::optional min_length{}; - std::optional max_length{}; - std::optional pattern{}; - // https://www.learnjsonschema.com/2020-12/format-annotation/format/ - std::optional format{}; - // number only keywords - schema_number minimum{}; - schema_number maximum{}; - schema_number exclusive_minimum{}; - schema_number exclusive_maximum{}; - schema_number multiple_of{}; - // object only keywords - std::optional min_properties{}; - std::optional max_properties{}; - // std::optional>> dependent_required{}; - // std::optional> required{}; - // array only keywords - std::optional min_items{}; - std::optional max_items{}; - std::optional min_contains{}; - std::optional max_contains{}; - std::optional unique_items{}; - - // metadata - std::optional tfc_metadata{}; - - static constexpr auto schema_attributes{ true }; // allowance flag to indicate metadata within glz::Object - - // TODO switch to using variants when we have write support to get rid of nulls - // TODO We should be able to generate the json schema compiletime - struct glaze { - using T = schema; - // clang-format off - static constexpr auto value = glz::object( - "$ref", &T::ref, // - "title", &T::title, // - "description", &T::description, // - "default", &T::default_value, // - "deprecated", &T::deprecated, // -// "examples", &T::examples, // - "readOnly", &T::read_only, // - "writeOnly", &T::write_only, // - "const", &T::constant, // - "minLength", &T::min_length, // - "maxLength", &T::max_length, // - "pattern", &T::pattern, - "format", &T::format, // - "minimum", &T::minimum, // - "maximum", &T::maximum, // - "exclusiveMinimum", &T::exclusive_minimum, // - "exclusiveMaximum", &T::exclusive_maximum, // - "multipleOf", &T::multiple_of, // - "minProperties", &T::min_properties, // - "maxProperties", &T::max_properties, // -// "dependentRequired", &T::dependent_required, // -// "required", &T::required, // - "minItems", &T::min_items, // - "maxItems", &T::max_items, // - "minContains", &T::min_contains, // - "maxContains", &T::max_contains, // - "uniqueItems", &T::unique_items, // - "x-tfc", &T::tfc_metadata - ); - // clang-format on - }; -}; +using schema = glz::schema; namespace detail { -struct schematic { - std::optional> type{}; - std::optional>> properties{}; // glaze_object - std::optional items{}; // array - std::optional> additionalProperties{}; // map - std::optional>> defs{}; - std::optional> enumeration{}; // enum - std::optional> oneOf{}; - schema attributes{}; -}; -} // namespace detail -} // namespace tfc::json - -template <> -struct glz::meta { - static constexpr std::string_view name = "glz::detail::schema"; - using T = tfc::json::detail::schematic; - // clang-format off - static constexpr auto value = glz::object( - "type", &T::type, // - "properties", &T::properties, // - "items", &T::items, // - "additionalProperties", &T::additionalProperties, // - "$defs", &T::defs, // - "enum", &T::enumeration, // - "oneOf", &T::oneOf, // - "title", [](auto&& self) -> auto& { return self.attributes.title; }, // - "description", [](auto&& self) -> auto& { return self.attributes.description; }, // - "default", [](auto&& self) -> auto& { return self.attributes.default_value; }, // - "deprecated", [](auto&& self) -> auto& { return self.attributes.deprecated; }, // - // "examples", [](auto&& self) -> auto& { return self.attributes.examples; }, // - "readOnly", [](auto&& self) -> auto& { return self.attributes.read_only; }, // - "writeOnly", [](auto&& self) -> auto& { return self.attributes.write_only; }, // - "const", [](auto&& self) -> auto& { return self.attributes.constant; }, // - "minLength", [](auto&& self) -> auto& { return self.attributes.min_length; }, // - "maxLength", [](auto&& self) -> auto& { return self.attributes.max_length; }, // - "pattern", [](auto&& self) -> auto& { return self.attributes.pattern; }, - "format", [](auto&& self) -> auto& { return self.attributes.format; }, - "minimum", [](auto&& self) -> auto& { return self.attributes.minimum; }, // - "maximum", [](auto&& self) -> auto& { return self.attributes.maximum; }, // - "exclusiveMinimum", [](auto&& self) -> auto& { return self.attributes.exclusive_minimum; }, // - "exclusiveMaximum", [](auto&& self) -> auto& { return self.attributes.exclusive_maximum; }, // - "multipleOf", [](auto&& self) -> auto& { return self.attributes.multiple_of; }, // - "minProperties", [](auto&& self) -> auto& { return self.attributes.min_properties; }, // - "maxProperties", [](auto&& self) -> auto& { return self.attributes.max_properties; }, // - // "dependentRequired", [](auto&& self) -> auto& { return self.attributes.dependent_required; }, // - // "required", [](auto&& self) -> auto& { return self.attributes.required; }, // - "minItems", [](auto&& self) -> auto& { return self.attributes.min_items; }, // - "maxItems", [](auto&& self) -> auto& { return self.attributes.max_items; }, // - "minContains", [](auto&& self) -> auto& { return self.attributes.min_contains; }, // - "maxContains", [](auto&& self) -> auto& { return self.attributes.max_contains; }, // - "uniqueItems", [](auto&& self) -> auto& { return self.attributes.unique_items; }, // - "x-tfc", [](auto&& self) -> auto& { return self.attributes.tfc_metadata; } - ); - // clang-format on -}; - -template <> -struct glz::meta { - using enum tfc::json::defined_formats; - static constexpr std::string_view name = "defined_formats"; - // clang-format off - static constexpr auto value = glz::enumerate( - "date-time", datetime, - "date", date, - "time", time, - "duration", duration, - "email", email, - "idn-email", idn_email, - "hostname", hostname, - "idn-hostname", idn_hostname, - "ipv4", ipv4, - "ipv6",ipv6, - "uri", uri, - "uri-reference", uri_reference, - "iri",iri, - "iri-reference", iri_reference, - "uuid", uuid, - "uri-template", uri_template, - "json-pointer", json_pointer, - "relative-json-pointer", relative_json_pointer, - "regex", regex); - // clang-format on -}; - -namespace tfc::json { -namespace detail { -template -struct to_json_schema { - template - static void op(auto& s, auto& defs) noexcept { - if constexpr (glz::detail::glaze_t && std::is_member_object_pointer_v>) { // &T::member - using val_t = glz::detail::member_t>; - to_json_schema::template op(s, defs); - } else if constexpr (glz::detail::glaze_const_value_t) { // &T::constexpr_member - using constexpr_val_t = glz::detail::member_t>; - static constexpr auto val_v{ *glz::meta_wrapper_v }; - if constexpr (glz::detail::glaze_enum_t) { - s.attributes.constant = glz::enum_name_v; - } else { - // General case, needs to be convertible to schema_any - s.attributes.constant = val_v; - } - to_json_schema::template op(s, defs); - } else { - // todo static_assert, it is more beneficial to get compile error instead of default everything - [] { - static_assert(flag, "Please provide a schema type for your given type"); - } - (); - } - } -}; - -template - requires(std::same_as || std::same_as::reference> || - std::same_as::const_reference>) -struct to_json_schema { - template - static void op(auto& s, auto&) noexcept { - s.type = { "boolean" }; - } -}; - -template -struct to_json_schema { - template - static void op(auto& s, auto&) noexcept { - if constexpr (std::integral) { - s.type = { "integer" }; - s.attributes.minimum = static_cast(std::numeric_limits::lowest()); - s.attributes.maximum = static_cast(std::numeric_limits::max()); - } else { - s.type = { "number" }; - s.attributes.minimum = std::numeric_limits::lowest(); - s.attributes.maximum = std::numeric_limits::max(); - } - } -}; - -template - requires glz::detail::str_t || glz::detail::char_t -struct to_json_schema { - template - static void op(auto& s, auto&) noexcept { - s.type = { "string" }; - } -}; - -template -struct to_json_schema { - template - static void op(auto& s, auto&) noexcept { - s.type = { "null" }; - s.attributes.constant = std::monostate{}; - } -}; - -template -struct to_json_schema { - template - static void op(auto& s, auto&) noexcept { - s.type = { "string" }; - - // TODO use oneOf instead of enum to handle doc comments - using V = std::decay_t; - static constexpr auto N = std::tuple_size_v>; - // s.enumeration = std::vector(N); - // for_each([&](auto I) { - // static constexpr auto item = std::get(meta_v); - // (*s.enumeration)[I.value] = std::get<0>(item); - // }); - s.oneOf = std::vector(N); - glz::for_each([&](auto I) { - static constexpr auto item = glz::get(glz::meta_v); - auto& enumeration = (*s.oneOf)[I.value]; - enumeration.attributes.constant = glz::get<0>(item); - enumeration.attributes.title = glz::get<0>(item); - if constexpr (std::tuple_size_v > 2) { - using additional_data_type = decltype(glz::get<2>(item)); - if constexpr (std::is_convertible_v) { - enumeration.attributes.description = glz::get<2>(item); - } else if constexpr (std::is_convertible_v) { - enumeration.attributes = glz::get<2>(item); - } - } - }); - } -}; - -template -struct to_json_schema> { - template - static void op(auto& s, auto&) noexcept { - s.type = { "number", "string", "boolean", "object", "array", "null" }; - } -}; - -template -struct is_std_array { - static constexpr auto value{ false }; -}; -template -struct is_std_array> { - static constexpr auto value{ true }; -}; - -template -concept has_fixed_size = requires { - requires is_std_array::value; // todo something else with fixed T::size -}; -static_assert(has_fixed_size>); -static_assert(!has_fixed_size>); - -template -struct get_size { - static constexpr auto value{ T::size }; -}; - -template -struct get_size> { - static constexpr auto value{ siz }; -}; -template -static constexpr auto get_size_v{ get_size::value }; - -template -struct to_json_schema { - template - static void op(auto& s, auto& defs) noexcept { - using V = std::decay_t>>; - s.type = { "array" }; - if constexpr (has_fixed_size) { - s.attributes.min_items = get_size_v; - s.attributes.max_items = get_size_v; - } - auto& def = defs[glz::name_v]; - if (!def.type) { - to_json_schema::template op(def, defs); - } - s.items = schema{ glz::detail::join_v, glz::name_v> }; - } -}; - -template -struct to_json_schema { - template - static void op(auto& s, auto& defs) noexcept { - using V = std::decay_t>>>; - s.type = { "object" }; - auto& def = defs[glz::name_v]; - if (!def.type) { - to_json_schema::template op(def, defs); - } - s.additionalProperties = schema{ glz::detail::join_v, glz::name_v> }; - } -}; - -template -struct to_json_schema { - template - static void op(auto& s, auto& defs) noexcept { - using V = std::decay_t>())>; - to_json_schema::template op(s, defs); - (*s.type).emplace_back("null"); - } -}; - -template -struct to_json_schema { - template - static void op(auto& s, auto& defs) noexcept { - static constexpr auto N = std::variant_size_v; - s.type = { "number", "string", "boolean", "object", "array", "null" }; - s.oneOf = std::vector(N); - glz::for_each([&](auto I) { - using V = std::decay_t>; - auto& schema_val = (*s.oneOf)[I.value]; - schema_val.attributes.title = glz::name_v; // please MAKE sure you declare name within variants - // TODO use ref to avoid duplication in schema - to_json_schema::template op(schema_val, defs); - constexpr bool glaze_object = glz::detail::glaze_object_t; - if constexpr (glaze_object) { - auto& def = defs[glz::name_v]; - if (!def.type) { - to_json_schema::template op(def, defs); - } - if constexpr (!glz::tag_v.empty()) { - (*schema_val.properties)[glz::tag_v] = - schema{ .ref = glz::detail::join_v, glz::name_v>, - .constant = glz::ids_v[I] }; - // TODO use enum or oneOf to get the ids_v to validate type name - } - } - }); - } -}; - -template - requires glz::detail::glaze_array_t> || glz::detail::tuple_t> -struct to_json_schema { - template - static void op(auto& s, auto&) noexcept { - // TODO: Actually handle this. We can specify a schema per item in items - // We can also do size restrictions on static arrays - s.type = { "array" }; - } -}; - -auto consteval has_slash(std::string_view str) noexcept -> bool { - return std::ranges::any_of(str, [](auto const character) { return character == '/'; }); -} - -template -struct to_json_schema { - template - static void op(auto& s, auto& defs) noexcept { - s.type = { "object" }; - - using V = std::decay_t; - static constexpr auto N = std::tuple_size_v>; - s.properties = std::map>(); - glz::for_each([&](auto I) { - static constexpr auto item = glz::get(glz::meta_v); - using mptr_t = decltype(glz::get<1>(item)); - using val_t = std::decay_t>; - auto& def = defs[glz::name_v]; - static_assert(!has_slash(glz::name_v), "Slashes in json schema references are not allowed"); - auto ref_val = schema{ glz::detail::join_v, glz::name_v> }; - // clang-format off - if constexpr (std::tuple_size_v > 2) { - // clang-format on - using additional_data_type = decltype(glz::get<2>(item)); - if constexpr (std::is_convertible_v) { - ref_val.description = glz::get<2>(item); - } else if constexpr (std::is_convertible_v) { - ref_val = glz::get<2>(item); - ref_val.ref = glz::detail::join_v, glz::name_v>; - } - } - (*s.properties)[glz::get<0>(item)] = ref_val; - - if (!def.type) { - to_json_schema::template op(def, defs); - } - }); - s.additionalProperties = false; - } -}; +// +// template +// struct to_json_schema { +// template +// static void op(auto& schema, auto& defs) noexcept +// { +// glz::detail::to_json_schema::op<>() +// } +// }; } // namespace detail -template -inline void write_json_schema(Buffer&& buffer) noexcept { - detail::schematic s{}; - s.defs.emplace(); - detail::to_json_schema>::template op(s, *s.defs); - write(std::move(s), std::forward(buffer)); -} - -template +template inline auto write_json_schema() noexcept { - std::string buffer{}; - detail::schematic s{}; - s.defs.emplace(); - detail::to_json_schema>::template op(s, *s.defs); - glz::write(std::move(s), buffer); - return buffer; + return glz::write_json_schema(); } } // namespace tfc::json diff --git a/libs/stx/inc/public/tfc/utils/units_glaze_meta.hpp b/libs/stx/inc/public/tfc/utils/units_glaze_meta.hpp index 069c809d56..db8eccf68a 100644 --- a/libs/stx/inc/public/tfc/utils/units_glaze_meta.hpp +++ b/libs/stx/inc/public/tfc/utils/units_glaze_meta.hpp @@ -67,7 +67,7 @@ struct glz::meta> { static auto constexpr name{ tfc::stx::string_view_join_v, postfix> }; }; -namespace tfc::json::detail { +namespace glz::detail { template struct to_json_schema; @@ -88,21 +88,22 @@ struct to_json_schema> { static constexpr mp_units::ratio ratio{ mp_units::as_ratio(ref_t) }; static constexpr auto dimension{ tfc::unit::dimension_name() }; template - static void op(auto& schema, auto& defs) { - auto& data = schema.attributes.tfc_metadata; - if (!data.has_value()) { - data = tfc::json::schema_meta{}; - } - data->unit = schema_meta::unit_meta{ .unit_ascii = unit_ascii, .unit_unicode = unit_unicode }; - data->dimension = dimension; - if constexpr (mp_units::Magnitude) { - data->ratio = tfc::json::schema_meta::ratio_impl{ .numerator = ratio.num, .denominator = ratio.den }; - } - to_json_schema::template op(schema, defs); + static void op([[maybe_unused]] auto& schema, [[maybe_unused]] auto& defs) { + // fix in https://github.com/Skaginn3x/framework/issues/555 + // auto& data = schema.attributes.tfc_metadata; + // if (!data.has_value()) { + // data = tfc::json::schema_meta{}; + // } + // data->unit = schema_meta::unit_meta{ .unit_ascii = unit_ascii, .unit_unicode = unit_unicode }; + // data->dimension = dimension; + // if constexpr (mp_units::Magnitude) { + // data->ratio = tfc::json::schema_meta::ratio_impl{ .numerator = ratio.num, .denominator = ratio.den }; + // } + // to_json_schema::template op(schema, defs); } }; -} // namespace tfc::json::detail +} // namespace glz::detail namespace tfc::unit { template diff --git a/libs/stx/inc/public/tfc/utils/uuids_glaze_meta.hpp b/libs/stx/inc/public/tfc/utils/uuids_glaze_meta.hpp index 5bde754419..8771021dd4 100644 --- a/libs/stx/inc/public/tfc/utils/uuids_glaze_meta.hpp +++ b/libs/stx/inc/public/tfc/utils/uuids_glaze_meta.hpp @@ -35,11 +35,6 @@ struct to_json { } }; -} // namespace detail -} // namespace glz - -namespace tfc::json::detail { - template struct to_json_schema; @@ -47,10 +42,12 @@ template <> struct to_json_schema { template static void op(auto& schema, auto& defs) { - using enum tfc::json::defined_formats; - schema.attributes.format = uuid; + // fix in https://github.com/Skaginn3x/framework/issues/555 + // using enum tfc::json::defined_formats; + // schema.attributes.format = uuid; to_json_schema::op(schema, defs); } }; -} // namespace tfc::json::detail +} // namespace detail +} // namespace glz diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json index 6d6b6e6496..0898399a0b 100644 --- a/vcpkg-configuration.json +++ b/vcpkg-configuration.json @@ -2,7 +2,7 @@ "default-registry": { "kind": "git", "repository": "https://github.com/microsoft/vcpkg", - "baseline": "a34c873a9717a888f58dc05268dea15592c2f0ff" + "baseline": "66a252f70eebdd744c02d7ab8c1cc6fe123c70ee" }, "registries": [ {