|
|
@@ -15,10 +15,9 @@
|
|
|
#include <jvalidate/constraint/string_constraint.h>
|
|
|
|
|
|
#include <jvalidate/detail/expect.h>
|
|
|
-#include <jvalidate/detail/reference.h>
|
|
|
+#include <jvalidate/detail/parser_context.h>
|
|
|
#include <jvalidate/enum.h>
|
|
|
#include <jvalidate/forward.h>
|
|
|
-#include <jvalidate/parser_context.h>
|
|
|
|
|
|
namespace jvalidate {
|
|
|
template <Adapter A> class ConstraintFactory {
|
|
|
@@ -26,7 +25,7 @@ public:
|
|
|
using pConstraint = std::unique_ptr<constraint::Constraint>;
|
|
|
using Object = decltype(std::declval<A>().as_object());
|
|
|
|
|
|
- using MakeConstraint = std::function<pConstraint(ParserContext<A> const &)>;
|
|
|
+ using MakeConstraint = std::function<pConstraint(detail::ParserContext<A> const &)>;
|
|
|
using VersionedMakeConstraint = std::map<schema::Version, MakeConstraint, std::greater<>>;
|
|
|
|
|
|
private:
|
|
|
@@ -104,16 +103,16 @@ public:
|
|
|
|
|
|
// SECTION: Untyped Constraints
|
|
|
|
|
|
- static pConstraint warnUnimplemented(ParserContext<A> const & context) {
|
|
|
+ static pConstraint warnUnimplemented(detail::ParserContext<A> const & context) {
|
|
|
std::cerr << "Unimplemented constraint " << context.where << "\n";
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
- static pConstraint fatalUnimplemented(ParserContext<A> const & context) {
|
|
|
+ static pConstraint fatalUnimplemented(detail::ParserContext<A> const & context) {
|
|
|
JVALIDATE_THROW(std::runtime_error, "Unimplemented constraint " << context.where);
|
|
|
}
|
|
|
|
|
|
- static auto type(ParserContext<A> const & context) {
|
|
|
+ static auto type(detail::ParserContext<A> const & context) {
|
|
|
static std::unordered_map<std::string_view, adapter::Type> const s_type_names{
|
|
|
{"null", adapter::Type::Null}, {"boolean", adapter::Type::Boolean},
|
|
|
{"integer", adapter::Type::Integer}, {"number", adapter::Type::Number},
|
|
|
@@ -139,12 +138,12 @@ public:
|
|
|
return std::make_unique<constraint::TypeConstraint>(types);
|
|
|
}
|
|
|
|
|
|
- static auto ifThenElse(ParserContext<A> const & context) {
|
|
|
+ static auto ifThenElse(detail::ParserContext<A> const & context) {
|
|
|
return std::make_unique<constraint::ConditionalConstraint>(
|
|
|
context.node(), context.neighbor("then").node(), context.neighbor("else").node());
|
|
|
}
|
|
|
|
|
|
- static auto isInEnumuration(ParserContext<A> const & context) {
|
|
|
+ static auto isInEnumuration(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Array);
|
|
|
|
|
|
std::vector<std::unique_ptr<adapter::Const const>> rval;
|
|
|
@@ -155,11 +154,11 @@ public:
|
|
|
return std::make_unique<constraint::EnumConstraint>(std::move(rval));
|
|
|
}
|
|
|
|
|
|
- static auto isConstant(ParserContext<A> const & context) {
|
|
|
+ static auto isConstant(detail::ParserContext<A> const & context) {
|
|
|
return std::make_unique<constraint::EnumConstraint>(context.schema.freeze());
|
|
|
}
|
|
|
|
|
|
- static auto allOf(ParserContext<A> const & context) {
|
|
|
+ static auto allOf(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Array);
|
|
|
|
|
|
std::vector<schema::Node const *> rval;
|
|
|
@@ -172,7 +171,7 @@ public:
|
|
|
return std::make_unique<constraint::AllOfConstraint>(rval);
|
|
|
}
|
|
|
|
|
|
- static auto anyOf(ParserContext<A> const & context) {
|
|
|
+ static auto anyOf(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Array);
|
|
|
|
|
|
std::vector<schema::Node const *> rval;
|
|
|
@@ -185,7 +184,7 @@ public:
|
|
|
return std::make_unique<constraint::AnyOfConstraint>(rval);
|
|
|
}
|
|
|
|
|
|
- static auto oneOf(ParserContext<A> const & context) {
|
|
|
+ static auto oneOf(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Array);
|
|
|
|
|
|
std::vector<schema::Node const *> rval;
|
|
|
@@ -198,13 +197,13 @@ public:
|
|
|
return std::make_unique<constraint::OneOfConstraint>(rval);
|
|
|
}
|
|
|
|
|
|
- static auto isNot(ParserContext<A> const & context) {
|
|
|
+ static auto isNot(detail::ParserContext<A> const & context) {
|
|
|
return std::make_unique<constraint::NotConstraint>(context.node());
|
|
|
}
|
|
|
|
|
|
// SECTION: Numeric Constraints
|
|
|
|
|
|
- static auto minimum(ParserContext<A> const & context) {
|
|
|
+ static auto minimum(detail::ParserContext<A> const & context) {
|
|
|
double value = context.schema.as_number();
|
|
|
if (context.version < schema::Version::Draft06 &&
|
|
|
context.parent->contains("exclusiveMinimum")) {
|
|
|
@@ -215,12 +214,12 @@ public:
|
|
|
return std::make_unique<constraint::MinimumConstraint>(value, false);
|
|
|
}
|
|
|
|
|
|
- static pConstraint exclusiveMinimum(ParserContext<A> const & context) {
|
|
|
+ static pConstraint exclusiveMinimum(detail::ParserContext<A> const & context) {
|
|
|
double value = context.schema.as_number();
|
|
|
return std::make_unique<constraint::MinimumConstraint>(value, true);
|
|
|
}
|
|
|
|
|
|
- static auto maximum(ParserContext<A> const & context) {
|
|
|
+ static auto maximum(detail::ParserContext<A> const & context) {
|
|
|
double value = context.schema.as_number();
|
|
|
if (context.version < schema::Version::Draft06 &&
|
|
|
context.parent->contains("exclusiveMaximum")) {
|
|
|
@@ -231,35 +230,35 @@ public:
|
|
|
return std::make_unique<constraint::MaximumConstraint>(value, false);
|
|
|
}
|
|
|
|
|
|
- static pConstraint exclusiveMaximum(ParserContext<A> const & context) {
|
|
|
+ static pConstraint exclusiveMaximum(detail::ParserContext<A> const & context) {
|
|
|
double value = context.schema.as_number();
|
|
|
return std::make_unique<constraint::MaximumConstraint>(value, true);
|
|
|
}
|
|
|
|
|
|
- static auto multipleOf(ParserContext<A> const & context) {
|
|
|
+ static auto multipleOf(detail::ParserContext<A> const & context) {
|
|
|
int64_t value = context.schema.as_integer();
|
|
|
return std::make_unique<constraint::MultipleOfConstraint>(value);
|
|
|
}
|
|
|
|
|
|
// SECTION: String Constraints
|
|
|
|
|
|
- static auto minLength(ParserContext<A> const & context) {
|
|
|
+ static auto minLength(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Integer);
|
|
|
return std::make_unique<constraint::MinLengthConstraint>(context.schema.as_integer());
|
|
|
}
|
|
|
|
|
|
- static auto maxLength(ParserContext<A> const & context) {
|
|
|
+ static auto maxLength(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Integer);
|
|
|
return std::make_unique<constraint::MaxLengthConstraint>(context.schema.as_integer());
|
|
|
}
|
|
|
|
|
|
- static auto pattern(ParserContext<A> const & context) {
|
|
|
+ static auto pattern(detail::ParserContext<A> const & context) {
|
|
|
return std::make_unique<constraint::PatternConstraint>(context.schema.as_string());
|
|
|
}
|
|
|
|
|
|
// SECTION: Array Constraints
|
|
|
|
|
|
- static auto contains(ParserContext<A> const & context) {
|
|
|
+ static auto contains(detail::ParserContext<A> const & context) {
|
|
|
if (context.version < schema::Version::Draft2019_09) {
|
|
|
return std::make_unique<constraint::ContainsConstraint>(context.node());
|
|
|
}
|
|
|
@@ -276,17 +275,17 @@ public:
|
|
|
return std::make_unique<constraint::ContainsConstraint>(context.node(), minimum, maximum);
|
|
|
}
|
|
|
|
|
|
- static auto minItems(ParserContext<A> const & context) {
|
|
|
+ static auto minItems(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Integer);
|
|
|
return std::make_unique<constraint::MinItemsConstraint>(context.schema.as_integer());
|
|
|
}
|
|
|
|
|
|
- static auto maxItems(ParserContext<A> const & context) {
|
|
|
+ static auto maxItems(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Integer);
|
|
|
return std::make_unique<constraint::MaxItemsConstraint>(context.schema.as_integer());
|
|
|
}
|
|
|
|
|
|
- static auto prefixItems(ParserContext<A> const & context) {
|
|
|
+ static auto prefixItems(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Array);
|
|
|
|
|
|
std::vector<schema::Node const *> rval;
|
|
|
@@ -299,7 +298,7 @@ public:
|
|
|
return std::make_unique<constraint::TupleConstraint>(rval);
|
|
|
}
|
|
|
|
|
|
- static pConstraint additionalItems(ParserContext<A> const & context) {
|
|
|
+ static pConstraint additionalItems(detail::ParserContext<A> const & context) {
|
|
|
std::string const prefix =
|
|
|
context.version >= schema::Version::Draft2020_12 ? "prefixItems" : "items";
|
|
|
|
|
|
@@ -318,7 +317,7 @@ public:
|
|
|
return std::make_unique<C>(context.node(), start_after);
|
|
|
}
|
|
|
|
|
|
- static pConstraint itemsTupleOrVector(ParserContext<A> const & context) {
|
|
|
+ static pConstraint itemsTupleOrVector(detail::ParserContext<A> const & context) {
|
|
|
if (context.schema.type() == adapter::Type::Array) {
|
|
|
return prefixItems(context);
|
|
|
}
|
|
|
@@ -326,11 +325,11 @@ public:
|
|
|
return additionalItems(context);
|
|
|
}
|
|
|
|
|
|
- static auto unevaluatedItems(ParserContext<A> const & context) {
|
|
|
+ static auto unevaluatedItems(detail::ParserContext<A> const & context) {
|
|
|
return std::make_unique<constraint::UnevaluatedItemsConstraint>(context.node());
|
|
|
}
|
|
|
|
|
|
- static pConstraint uniqueItems(ParserContext<A> const & context) {
|
|
|
+ static pConstraint uniqueItems(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Boolean);
|
|
|
if (not context.schema.as_boolean()) {
|
|
|
return nullptr;
|
|
|
@@ -341,7 +340,7 @@ public:
|
|
|
|
|
|
// SECTION: Object Constraints
|
|
|
|
|
|
- static auto required(ParserContext<A> const & context) {
|
|
|
+ static auto required(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Array);
|
|
|
|
|
|
std::unordered_set<std::string> rval;
|
|
|
@@ -353,17 +352,17 @@ public:
|
|
|
return std::make_unique<constraint::RequiredConstraint>(rval);
|
|
|
}
|
|
|
|
|
|
- static auto minProperties(ParserContext<A> const & context) {
|
|
|
+ static auto minProperties(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Integer);
|
|
|
return std::make_unique<constraint::MinPropertiesConstraint>(context.schema.as_integer());
|
|
|
}
|
|
|
|
|
|
- static auto maxProperties(ParserContext<A> const & context) {
|
|
|
+ static auto maxProperties(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Integer);
|
|
|
return std::make_unique<constraint::MaxPropertiesConstraint>(context.schema.as_integer());
|
|
|
}
|
|
|
|
|
|
- static auto patternProperties(ParserContext<A> const & context) {
|
|
|
+ static auto patternProperties(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
std::vector<std::pair<std::string, schema::Node const *>> rval;
|
|
|
@@ -374,7 +373,7 @@ public:
|
|
|
return std::make_unique<constraint::PatternPropertiesConstraint>(rval);
|
|
|
}
|
|
|
|
|
|
- static auto properties(ParserContext<A> const & context) {
|
|
|
+ static auto properties(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
std::map<std::string, schema::Node const *> rval;
|
|
|
@@ -385,15 +384,15 @@ public:
|
|
|
return std::make_unique<constraint::PropertiesConstraint>(rval);
|
|
|
}
|
|
|
|
|
|
- static auto propertyNames(ParserContext<A> const & context) {
|
|
|
+ static auto propertyNames(detail::ParserContext<A> const & context) {
|
|
|
return std::make_unique<constraint::PropertyNamesConstraint>(context.node());
|
|
|
}
|
|
|
|
|
|
- static auto unevaluatedProperties(ParserContext<A> const & context) {
|
|
|
+ static auto unevaluatedProperties(detail::ParserContext<A> const & context) {
|
|
|
return std::make_unique<constraint::UnevaluatedPropertiesConstraint>(context.node());
|
|
|
}
|
|
|
|
|
|
- static auto additionalProperties(ParserContext<A> const & context) {
|
|
|
+ static auto additionalProperties(detail::ParserContext<A> const & context) {
|
|
|
std::unordered_set<std::string> properties;
|
|
|
std::vector<std::string> patterns;
|
|
|
|
|
|
@@ -418,7 +417,7 @@ public:
|
|
|
return std::make_unique<C>(context.node(), properties, patterns);
|
|
|
}
|
|
|
|
|
|
- static auto dependencies(ParserContext<A> const & context) {
|
|
|
+ static auto dependencies(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
std::map<std::string, schema::Node const *> schemas;
|
|
|
@@ -437,7 +436,7 @@ public:
|
|
|
return std::make_unique<constraint::DependenciesConstraint>(schemas, required);
|
|
|
}
|
|
|
|
|
|
- static auto dependentSchemas(ParserContext<A> const & context) {
|
|
|
+ static auto dependentSchemas(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
std::map<std::string, schema::Node const *> rval;
|
|
|
@@ -448,7 +447,7 @@ public:
|
|
|
return std::make_unique<constraint::DependenciesConstraint>(rval);
|
|
|
}
|
|
|
|
|
|
- static auto dependentRequired(ParserContext<A> const & context) {
|
|
|
+ static auto dependentRequired(detail::ParserContext<A> const & context) {
|
|
|
EXPECT(context.schema.type() == adapter::Type::Object);
|
|
|
|
|
|
std::map<std::string, std::unordered_set<std::string>> rval;
|