mirror of
https://github.com/tristanpenman/valijson.git
synced 2025-09-27 16:29:33 +02:00
Update AllOfConstraint and AnyOfConstraint classes to use custom allocator
This commit is contained in:
parent
c54bf3ba87
commit
d534c49393
@ -31,9 +31,6 @@
|
||||
#include <valijson/schema.hpp>
|
||||
|
||||
namespace valijson {
|
||||
|
||||
class Schema;
|
||||
|
||||
namespace constraints {
|
||||
|
||||
/**
|
||||
@ -43,15 +40,40 @@ namespace constraints {
|
||||
* validate against. If a value fails to validate against any of these sub-
|
||||
* schemas, then validation fails.
|
||||
*/
|
||||
struct AllOfConstraint: BasicConstraint<AllOfConstraint>
|
||||
class AllOfConstraint: public BasicConstraint<AllOfConstraint>
|
||||
{
|
||||
typedef std::vector<const Subschema *> Schemas;
|
||||
public:
|
||||
AllOfConstraint()
|
||||
: subschemas(Allocator::rebind<const Subschema *>::other(allocator)) { }
|
||||
|
||||
AllOfConstraint(const Schemas &schemas)
|
||||
: schemas(schemas) { }
|
||||
AllOfConstraint(CustomAlloc allocFn, CustomFree freeFn)
|
||||
: BasicConstraint(allocFn, freeFn),
|
||||
subschemas(Allocator::rebind<const Subschema *>::other(allocator)) { }
|
||||
|
||||
/// Collection of schemas that must all be satisfied
|
||||
const Schemas schemas;
|
||||
void addSubschema(const Subschema *subschema)
|
||||
{
|
||||
subschemas.push_back(subschema);
|
||||
}
|
||||
|
||||
template<typename FunctorType>
|
||||
void applyToSubschemas(const FunctorType &fn) const
|
||||
{
|
||||
unsigned int index = 0;
|
||||
BOOST_FOREACH( const Subschema *subschema, subschemas ) {
|
||||
if (!fn(index, subschema)) {
|
||||
return;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::vector<const Subschema *,
|
||||
internal::CustomAllocator<const Subschema *> > Subschemas;
|
||||
|
||||
/// Collection of sub-schemas, all of which must be satisfied
|
||||
Subschemas subschemas;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -61,15 +83,40 @@ struct AllOfConstraint: BasicConstraint<AllOfConstraint>
|
||||
* validate against. If a value validates against one of these sub-schemas,
|
||||
* then the validation passes.
|
||||
*/
|
||||
struct AnyOfConstraint: BasicConstraint<AnyOfConstraint>
|
||||
class AnyOfConstraint: public BasicConstraint<AnyOfConstraint>
|
||||
{
|
||||
typedef std::vector<const Subschema *> Schemas;
|
||||
public:
|
||||
AnyOfConstraint()
|
||||
: subschemas(Allocator::rebind<const Subschema *>::other(allocator)) { }
|
||||
|
||||
AnyOfConstraint(const Schemas &schemas)
|
||||
: schemas(schemas) { }
|
||||
AnyOfConstraint(CustomAlloc allocFn, CustomFree freeFn)
|
||||
: BasicConstraint(allocFn, freeFn),
|
||||
subschemas(Allocator::rebind<const Subschema *>::other(allocator)) { }
|
||||
|
||||
/// Collection of schemas of which one must be satisfied
|
||||
const Schemas schemas;
|
||||
void addSubschema(const Subschema *subschema)
|
||||
{
|
||||
subschemas.push_back(subschema);
|
||||
}
|
||||
|
||||
template<typename FunctorType>
|
||||
void applyToSubschemas(const FunctorType &fn) const
|
||||
{
|
||||
unsigned int index = 0;
|
||||
BOOST_FOREACH( const Subschema *subschema, subschemas ) {
|
||||
if (!fn(index, subschema)) {
|
||||
return;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::vector<const Subschema *,
|
||||
internal::CustomAllocator<const Subschema *> > Subschemas;
|
||||
|
||||
/// Collection of sub-schemas, at least one of which must be satisfied
|
||||
Subschemas subschemas;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -146,29 +193,25 @@ public:
|
||||
}
|
||||
|
||||
template<typename FunctorType>
|
||||
bool applyToPropertyDependencies(const FunctorType &fn) const
|
||||
void applyToPropertyDependencies(const FunctorType &fn) const
|
||||
{
|
||||
BOOST_FOREACH( const PropertyDependencies::value_type &v,
|
||||
propertyDependencies ) {
|
||||
if (!fn(v.first, v.second)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename FunctorType>
|
||||
bool applyToSchemaDependencies(const FunctorType &fn) const
|
||||
void applyToSchemaDependencies(const FunctorType &fn) const
|
||||
{
|
||||
BOOST_FOREACH( const SchemaDependencies::value_type &v,
|
||||
schemaDependencies ) {
|
||||
if (!fn(v.first, v.second)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -496,16 +496,17 @@ private:
|
||||
"Expected array value for 'allOf' constraint.");
|
||||
}
|
||||
|
||||
constraints::AllOfConstraint::Schemas childSchemas;
|
||||
constraints::AllOfConstraint constraint;
|
||||
|
||||
int index = 0;
|
||||
BOOST_FOREACH ( const AdapterType schemaNode, node.asArray() ) {
|
||||
if (schemaNode.maybeObject()) {
|
||||
const std::string childPath = nodePath + "/" +
|
||||
boost::lexical_cast<std::string>(index);
|
||||
childSchemas.push_back(rootSchema.createSubschema());
|
||||
const Subschema *subschema = rootSchema.createSubschema();
|
||||
constraint.addSubschema(subschema);
|
||||
populateSchema<AdapterType>(rootSchema, rootNode, schemaNode,
|
||||
*childSchemas.back(), currentScope, childPath,
|
||||
fetchDoc);
|
||||
*subschema, currentScope, childPath, fetchDoc);
|
||||
index++;
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
@ -514,7 +515,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
return constraints::AllOfConstraint(childSchemas);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -548,16 +549,17 @@ private:
|
||||
"Expected array value for 'anyOf' constraint.");
|
||||
}
|
||||
|
||||
constraints::AnyOfConstraint::Schemas childSchemas;
|
||||
constraints::AnyOfConstraint constraint;
|
||||
|
||||
int index = 0;
|
||||
BOOST_FOREACH ( const AdapterType schemaNode, node.asArray() ) {
|
||||
if (schemaNode.maybeObject()) {
|
||||
const std::string childPath = nodePath + "/" +
|
||||
boost::lexical_cast<std::string>(index);
|
||||
childSchemas.push_back(rootSchema.createSubschema());
|
||||
const Subschema *subschema = rootSchema.createSubschema();
|
||||
constraint.addSubschema(subschema);
|
||||
populateSchema<AdapterType>(rootSchema, rootNode, schemaNode,
|
||||
*childSchemas.back(), currentScope, childPath,
|
||||
fetchDoc);
|
||||
*subschema, currentScope, childPath, fetchDoc);
|
||||
index++;
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
@ -566,7 +568,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
return constraints::AnyOfConstraint(childSchemas);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,27 +112,10 @@ public:
|
||||
*/
|
||||
virtual bool visit(const AllOfConstraint &constraint)
|
||||
{
|
||||
// Flag used to track validation status if errors are non-fatal
|
||||
bool validated = true;
|
||||
|
||||
// Validate against each child schema
|
||||
unsigned int index = 0;
|
||||
BOOST_FOREACH( const Subschema *subschema, constraint.schemas ) {
|
||||
|
||||
// Ensure that the target validates against child schema
|
||||
if (!validateSchema(*subschema)) {
|
||||
if (results) {
|
||||
validated = false;
|
||||
results->pushError(context,
|
||||
std::string("Failed to validate against child schema #") +
|
||||
boost::lexical_cast<std::string>(index) + " of allOf constraint.");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
constraint.applyToSubschemas(ValidateAllSubschemas(target, context,
|
||||
*this, results, &validated));
|
||||
|
||||
return validated;
|
||||
}
|
||||
@ -157,22 +140,17 @@ public:
|
||||
*/
|
||||
virtual bool visit(const AnyOfConstraint &constraint)
|
||||
{
|
||||
// Wrap the validationCallback() function below so that it will be
|
||||
// passed a reference to a constraint (_1), and a reference to the
|
||||
// visitor (*this).
|
||||
Schema::ApplyFunction fn(boost::bind(validationCallback, _1, *this));
|
||||
bool validated = false;
|
||||
|
||||
BOOST_FOREACH( const Subschema *subschema, constraint.schemas ) {
|
||||
if (subschema->apply(fn)) {
|
||||
return true;
|
||||
}
|
||||
constraint.applyToSubschemas(ValidateAtLeastOneSubschema(target,
|
||||
context, *this, results, &validated));
|
||||
|
||||
if (!validated && results) {
|
||||
results->pushError(context, "Failed to validate against any child "
|
||||
"schemas allowed by anyOf constraint.");
|
||||
}
|
||||
|
||||
if (results) {
|
||||
results->pushError(context, "Failed to validate against any child schemas allowed by anyOf constraint.");
|
||||
}
|
||||
|
||||
return false;
|
||||
return validated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1066,6 +1044,82 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
struct ValidateAllSubschemas
|
||||
{
|
||||
ValidateAllSubschemas(
|
||||
const AdapterType &adapter,
|
||||
const std::vector<std::string> &context,
|
||||
ValidationVisitor &validationVisitor,
|
||||
ValidationResults *results,
|
||||
bool *validated)
|
||||
: adapter(adapter),
|
||||
context(context),
|
||||
validationVisitor(validationVisitor),
|
||||
results(results),
|
||||
validated(validated) { }
|
||||
|
||||
bool operator()(unsigned int index, const Subschema *subschema) const
|
||||
{
|
||||
if (!validationVisitor.validateSchema(*subschema)) {
|
||||
if (validated) {
|
||||
*validated = false;
|
||||
}
|
||||
if (results) {
|
||||
results->pushError(context,
|
||||
"Failed to validate against child schema #" +
|
||||
boost::lexical_cast<std::string>(index) +
|
||||
" of allOf constraint.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const AdapterType &adapter;
|
||||
const std::vector<std::string> &context;
|
||||
ValidationVisitor &validationVisitor;
|
||||
ValidationResults * const results;
|
||||
bool * const validated;
|
||||
};
|
||||
|
||||
struct ValidateAtLeastOneSubschema
|
||||
{
|
||||
ValidateAtLeastOneSubschema(
|
||||
const AdapterType &adapter,
|
||||
const std::vector<std::string> &context,
|
||||
ValidationVisitor &validationVisitor,
|
||||
ValidationResults *results,
|
||||
bool *validated)
|
||||
: adapter(adapter),
|
||||
context(context),
|
||||
validationVisitor(validationVisitor),
|
||||
results(results),
|
||||
validated(validated) { }
|
||||
|
||||
bool operator()(unsigned int index, const Subschema *subschema) const
|
||||
{
|
||||
if (validationVisitor.validateSchema(*subschema)) {
|
||||
if (validated) {
|
||||
*validated = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const AdapterType &adapter;
|
||||
const std::vector<std::string> &context;
|
||||
ValidationVisitor &validationVisitor;
|
||||
ValidationResults * const results;
|
||||
bool * const validated;
|
||||
};
|
||||
|
||||
struct ValidatePropertyDependencies
|
||||
{
|
||||
ValidatePropertyDependencies(
|
||||
|
Loading…
x
Reference in New Issue
Block a user