#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jvalidate::detail { /** * @brief An ArrayAdapter implmenetation for JSON "types" which do not support * arrays. This is for example caused when attempting to apply json schema * validation to non-json types representation, such as a some forms of * PropertyTree implementations. * * This is specifically provided for making StringAdapter compatible with the * Adapter concept. */ template class UnsupportedArrayAdapter { public: size_t size() const { return 0; } CRTP operator[](size_t) const { throw std::runtime_error("stub implementation"); } std::vector::const_iterator begin() const { return {}; } std::vector::const_iterator end() const { return {}; } }; /** * @brief An ObjectAdapter implmenetation for JSON "types" which do not support * objects. This is for example caused when attempting to apply json schema * validation to non-json types representation. * * This is specifically provided for making StringAdapter compatible with the * Adapter concept. */ template class UnsupportedObjectAdapter { public: size_t size() const { return 0; } bool contains(std::string_view) const { return false; } CRTP operator[](std::string_view) const { throw std::runtime_error("stub implementation"); } std::map::const_iterator begin() const { return {}; } std::map::const_iterator end() const { return {}; } }; /** * @brief An Adapter for strings, required for implmenting propertyNames * constraints, which are applied to the keys of a JSON object. * * Unfortunately requires a large number of stub function implementations in * order to satisfy adapter::Adapter AND Adapter concept. */ class StringAdapter final : public adapter::Adapter { public: using value_type = std::string_view; explicit(false) StringAdapter(std::string_view value) : value_(value) {} adapter::Type type() const final { return adapter::Type::String; } bool as_boolean() const final { die("boolean"); } int64_t as_integer() const final { die("integer"); } double as_number() const final { die("number"); } std::string as_string() const final { return std::string(value_); } size_t array_size() const final { die("array"); } // NOLINTNEXTLINE(readability-convert-member-functions-to-static) UnsupportedArrayAdapter as_array() const { die("array"); } Status apply_array(adapter::AdapterCallback const &) const final { return Status::Noop; } size_t object_size() const final { die("object"); } // NOLINTNEXTLINE(readability-convert-member-functions-to-static) UnsupportedObjectAdapter as_object() const { die("object"); } Status apply_object(adapter::ObjectAdapterCallback const &) const final { return Status::Noop; } bool equals(adapter::Adapter const & rhs, bool strict) const final { if (std::optional const str = rhs.maybe_string(strict)) { return str == value_; } return false; } std::unique_ptr freeze() const final { return std::make_unique>(value_); } private: [[noreturn]] static void die(std::string const & expected) { throw std::runtime_error("StringAdapter is not an " + expected); } private: std::string_view value_; }; } template <> struct jvalidate::adapter::AdapterTraits { template using Adapter = jvalidate::detail::StringAdapter; using ConstAdapter = jvalidate::detail::StringAdapter; };