| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #pragma once
- #include <functional>
- #include <string>
- #include <type_traits>
- #include <variant>
- #define DISCARD1_IMPL(_, ...) __VA_ARGS__
- #define DISCARD1(...) DISCARD1_IMPL(__VA_ARGS__)
- #define FORWARD_DECLARE_STRUCT(TYPE) struct TYPE;
- #define COMMA_NAME(X) , X
- namespace jvalidate {
- class Schema;
- class Status;
- class URI;
- struct ValidationConfig;
- class ValidationResult;
- }
- namespace jvalidate::adapter {
- enum class Type : int8_t;
- class Adapter;
- class Const;
- using AdapterCallback = std::function<Status(adapter::Adapter const &)>;
- using ObjectAdapterCallback = std::function<Status(std::string const &, adapter::Adapter const &)>;
- template <typename> struct AdapterTraits;
- template <typename V> struct AdapterTraits<V const> : AdapterTraits<V> {};
- template <typename JSON> using AdapterFor = typename AdapterTraits<JSON>::template Adapter<JSON>;
- }
- namespace jvalidate::schema {
- enum class Version : int;
- class Node;
- }
- namespace jvalidate::constraint {
- #define CONSTRAINT_IMPLEMENTATION_LIST(X) \
- /* General Constraints - See jvalidate/constraint/general_constraint.h */ \
- X(TypeConstraint) \
- X(EnumConstraint) \
- X(AllOfConstraint) \
- X(AnyOfConstraint) \
- X(OneOfConstraint) \
- X(NotConstraint) \
- X(ConditionalConstraint) \
- /* Number Constraints - See jvalidate/constraint/number_constraint.h */ \
- X(MaximumConstraint) \
- X(MinimumConstraint) \
- X(MultipleOfConstraint) \
- /* String Constraints - See jvalidate/constraint/string_constraint.h */ \
- X(MaxLengthConstraint) \
- X(MinLengthConstraint) \
- X(PatternConstraint) \
- X(FormatConstraint) \
- /* Array Constraints - See jvalidate/constraint/array_constraint.h */ \
- X(AdditionalItemsConstraint) \
- X(ContainsConstraint) \
- X(MaxItemsConstraint) \
- X(MinItemsConstraint) \
- X(TupleConstraint) \
- X(UnevaluatedItemsConstraint) \
- X(UniqueItemsConstraint) \
- /* Object Constraints - See jvalidate/constraint/object_constraint.h */ \
- X(AdditionalPropertiesConstraint) \
- X(DependenciesConstraint) \
- X(MaxPropertiesConstraint) \
- X(MinPropertiesConstraint) \
- X(PatternPropertiesConstraint) \
- X(PropertiesConstraint) \
- X(PropertyNamesConstraint) \
- X(RequiredConstraint) \
- X(UnevaluatedPropertiesConstraint) \
- /* ExtensionConstraint - A special constraint for all user-defined constraints */ \
- X(ExtensionConstraint)
- CONSTRAINT_IMPLEMENTATION_LIST(FORWARD_DECLARE_STRUCT);
- using Constraint = std::variant<DISCARD1(CONSTRAINT_IMPLEMENTATION_LIST(COMMA_NAME))>;
- using SubConstraint = std::variant<schema::Node const *, std::unique_ptr<Constraint>>;
- }
- namespace jvalidate {
- template <typename It>
- concept ArrayIterator =
- std::forward_iterator<It> and std::is_default_constructible_v<It> and requires(It const it) {
- { *it } -> std::convertible_to<adapter::Adapter const &>;
- };
- template <typename It>
- concept ObjectIterator =
- std::forward_iterator<It> and std::is_default_constructible_v<It> and requires(It const it) {
- { it->first } -> std::convertible_to<std::string_view>;
- { it->second } -> std::convertible_to<adapter::Adapter const &>;
- };
- template <typename A>
- concept ArrayAdapter = requires(A const a) {
- { a.size() } -> std::convertible_to<std::size_t>;
- { a[0UL] } -> std::convertible_to<adapter::Adapter const &>;
- { a.begin() } -> ArrayIterator;
- { a.end() } -> ArrayIterator;
- };
- template <typename A>
- concept ObjectAdapter = requires(A const a) {
- { a.size() } -> std::convertible_to<std::size_t>;
- { a.contains("") } -> std::same_as<bool>;
- { a[""] } -> std::convertible_to<adapter::Adapter const &>;
- { a.begin() } -> ObjectIterator;
- { a.end() } -> ObjectIterator;
- };
- /**
- * @brief A concept representing the actual adapter form. Used in most code
- * that actually cares to interact with JSON, instead of having to define a
- * template like AdapterInterface<ArrayAdapter, ObjectAdapter> for the basic
- * adapter, or return pointers-to-interfaces in order to access array/object
- * data.
- *
- * This concept functionally defines an Adapter being an AdapterInterface with
- * an as_array and as_object method added on.
- */
- template <typename A>
- concept Adapter = std::is_base_of_v<adapter::Adapter, A> && requires(A const a) {
- typename A::value_type;
- { a.type() } -> std::same_as<adapter::Type>;
- { a.as_boolean() } -> std::same_as<bool>;
- { a.as_integer() } -> std::convertible_to<int64_t>;
- { a.as_number() } -> std::convertible_to<double>;
- { a.as_number() } -> std::floating_point;
- { a.as_object() } -> ObjectAdapter;
- { a.as_array() } -> ArrayAdapter;
- { a.array_size() } -> std::convertible_to<size_t>;
- { a.object_size() } -> std::convertible_to<size_t>;
- };
- template <typename A>
- concept MutableObject = ObjectAdapter<A> && requires(A const a) {
- { a.assign("", std::declval<adapter::Const>()) };
- };
- /**
- * @brief An extension of Adapter that is capable of altering the underlying
- * JSON node. In general, that means that a non-const ref is captured when
- * building an Adapter.
- *
- * Requires that we can assign both to "this", and to values at a key (in the
- * case of object type).
- * Implies that as_array is also a wrapper for mutable JSON.
- */
- template <typename A>
- concept MutableAdapter = Adapter<A> && requires(A const a) {
- { a.assign(std::declval<adapter::Const>()) };
- { a.assign(std::declval<adapter::Adapter>()) };
- { a.as_object() } -> MutableObject;
- };
- template <typename R>
- concept RegexEngine = std::constructible_from<std::string> && requires(R const regex) {
- { regex.search("") } -> std::same_as<bool>;
- };
- }
- namespace jvalidate {
- template <Adapter A> class ConstraintFactory;
- template <Adapter A> class DocumentCache;
- template <Adapter A, RegexEngine RE> class ValidationVisitor;
- template <RegexEngine RE> class ValidatorT;
- class Validator;
- template <Adapter A> using URIResolver = bool (*)(URI const &, typename A::value_type &);
- template <typename T, typename S>
- concept Not = not std::is_convertible_v<std::decay_t<S>, T>;
- }
- #undef FORWARD_DECLARE_STRUCT
- #undef COMMA_NAME
- #undef DISCARD1_IMPL
- #undef DISCARD1
|