mirror of
https://github.com/tristanpenman/valijson.git
synced 2024-12-12 18:20:27 +01:00
Update RequiredConstraint to use custom allocator, with better encapsulation
This commit is contained in:
parent
a0e1a2f74a
commit
05ba5bf711
@ -158,11 +158,11 @@ void addRequiredConstraint(Schema &schema)
|
|||||||
{
|
{
|
||||||
// Add a RequiredConstraint to the schema, specifying that the category,
|
// Add a RequiredConstraint to the schema, specifying that the category,
|
||||||
// price, and title properties must be present.
|
// price, and title properties must be present.
|
||||||
RequiredConstraint::RequiredProperties requiredProperties;
|
RequiredConstraint constraint;
|
||||||
requiredProperties.insert("category");
|
constraint.addRequiredProperty("category");
|
||||||
requiredProperties.insert("price");
|
constraint.addRequiredProperty("price");
|
||||||
requiredProperties.insert("title");
|
constraint.addRequiredProperty("title");
|
||||||
schema.addConstraint(RequiredConstraint(requiredProperties));
|
schema.addConstraint(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTypeConstraint(Schema &schema)
|
void addTypeConstraint(Schema &schema)
|
||||||
|
@ -552,17 +552,44 @@ struct PropertiesConstraint: BasicConstraint<PropertiesConstraint> {
|
|||||||
/**
|
/**
|
||||||
* @brief Represents a 'required' constraint.
|
* @brief Represents a 'required' constraint.
|
||||||
*/
|
*/
|
||||||
struct RequiredConstraint: BasicConstraint<RequiredConstraint>
|
class RequiredConstraint: public BasicConstraint<RequiredConstraint>
|
||||||
{
|
{
|
||||||
typedef std::set<std::string> RequiredProperties;
|
public:
|
||||||
|
RequiredConstraint()
|
||||||
|
: requiredProperties(std::less<String>(), allocator) { }
|
||||||
|
|
||||||
RequiredConstraint(const RequiredProperties &requiredProperties)
|
RequiredConstraint(CustomAlloc allocFn, CustomFree freeFn)
|
||||||
: requiredProperties(requiredProperties)
|
: BasicConstraint(allocFn, freeFn),
|
||||||
|
requiredProperties(std::less<String>(), allocator) { }
|
||||||
|
|
||||||
|
bool addRequiredProperty(const char *propertyName)
|
||||||
{
|
{
|
||||||
|
return requiredProperties.insert(String(propertyName,
|
||||||
|
Allocator::rebind<char>::other(allocator))).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RequiredProperties requiredProperties;
|
template<typename AllocatorType>
|
||||||
|
bool addRequiredProperty(const std::basic_string<char,
|
||||||
|
std::char_traits<char>, AllocatorType> &propertyName)
|
||||||
|
{
|
||||||
|
return addRequiredProperty(propertyName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FunctorType>
|
||||||
|
void applyToRequiredProperties(const FunctorType &fn) const
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( const String &propertyName, requiredProperties ) {
|
||||||
|
if (!fn(propertyName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::set<String, std::less<String>,
|
||||||
|
internal::CustomAllocator<String> > RequiredProperties;
|
||||||
|
|
||||||
|
RequiredProperties requiredProperties;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,13 +19,14 @@ struct MultipleOfConstraint;
|
|||||||
struct NotConstraint;
|
struct NotConstraint;
|
||||||
struct PatternConstraint;
|
struct PatternConstraint;
|
||||||
struct PropertiesConstraint;
|
struct PropertiesConstraint;
|
||||||
struct RequiredConstraint;
|
|
||||||
|
|
||||||
class AllOfConstraint;
|
class AllOfConstraint;
|
||||||
class AnyOfConstraint;
|
class AnyOfConstraint;
|
||||||
class DependenciesConstraint;
|
class DependenciesConstraint;
|
||||||
class LinearItemsConstraint;
|
class LinearItemsConstraint;
|
||||||
class OneOfConstraint;
|
class OneOfConstraint;
|
||||||
|
class RequiredConstraint;
|
||||||
class SingularItemsConstraint;
|
class SingularItemsConstraint;
|
||||||
class TypeConstraint;
|
class TypeConstraint;
|
||||||
class UniqueItemsConstraint;
|
class UniqueItemsConstraint;
|
||||||
|
@ -1372,9 +1372,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.asBool()) {
|
if (node.asBool()) {
|
||||||
constraints::RequiredConstraint::RequiredProperties requiredProperties;
|
constraints::RequiredConstraint constraint;
|
||||||
requiredProperties.insert(name);
|
constraint.addRequiredProperty(name);
|
||||||
return constraints::RequiredConstraint(requiredProperties);
|
return constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::none;
|
return boost::none;
|
||||||
@ -1395,15 +1395,18 @@ private:
|
|||||||
constraints::RequiredConstraint makeRequiredConstraint(
|
constraints::RequiredConstraint makeRequiredConstraint(
|
||||||
const AdapterType &node)
|
const AdapterType &node)
|
||||||
{
|
{
|
||||||
constraints::RequiredConstraint::RequiredProperties requiredProperties;
|
constraints::RequiredConstraint constraint;
|
||||||
|
|
||||||
BOOST_FOREACH( const AdapterType v, node.getArray() ) {
|
BOOST_FOREACH( const AdapterType v, node.getArray() ) {
|
||||||
if (!v.isString()) {
|
if (!v.isString()) {
|
||||||
// @todo throw exception
|
throw std::runtime_error("Expected required property name to "
|
||||||
|
"be a string value");
|
||||||
}
|
}
|
||||||
requiredProperties.insert(v.getString());
|
|
||||||
|
constraint.addRequiredProperty(v.getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return constraints::RequiredConstraint(requiredProperties);
|
return constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -887,23 +887,16 @@ public:
|
|||||||
{
|
{
|
||||||
if ((strictTypes && !target.isObject()) || !target.maybeObject()) {
|
if ((strictTypes && !target.isObject()) || !target.maybeObject()) {
|
||||||
if (results) {
|
if (results) {
|
||||||
results->pushError(context, "Object required to validate 'required' properties.");
|
results->pushError(context,
|
||||||
|
"Object required to validate 'required' properties.");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validated = true;
|
bool validated = true;
|
||||||
const typename AdapterType::Object object = target.asObject();
|
const typename AdapterType::Object object = target.asObject();
|
||||||
BOOST_FOREACH( const std::string &requiredProperty, constraint.requiredProperties ) {
|
constraint.applyToRequiredProperties(ValidateProperties(object, context,
|
||||||
if (object.find(requiredProperty) == object.end()) {
|
true, results != NULL, results, &validated));
|
||||||
if (results) {
|
|
||||||
results->pushError(context, "Missing required property '" + requiredProperty + "'.");
|
|
||||||
validated = false;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return validated;
|
return validated;
|
||||||
}
|
}
|
||||||
@ -1053,6 +1046,53 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Functor to validate the presence of a set of properties
|
||||||
|
*/
|
||||||
|
struct ValidateProperties
|
||||||
|
{
|
||||||
|
ValidateProperties(
|
||||||
|
const typename AdapterType::Object &object,
|
||||||
|
const std::vector<std::string> &context,
|
||||||
|
bool continueOnSuccess,
|
||||||
|
bool continueOnFailure,
|
||||||
|
ValidationResults *results,
|
||||||
|
bool *validated)
|
||||||
|
: object(object),
|
||||||
|
context(context),
|
||||||
|
continueOnSuccess(continueOnSuccess),
|
||||||
|
continueOnFailure(continueOnFailure),
|
||||||
|
results(results),
|
||||||
|
validated(validated) { }
|
||||||
|
|
||||||
|
template<typename StringType>
|
||||||
|
bool operator()(const StringType &property) const
|
||||||
|
{
|
||||||
|
if (object.find(property.c_str()) == object.end()) {
|
||||||
|
if (validated) {
|
||||||
|
*validated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results) {
|
||||||
|
results->pushError(context, "Missing required property '" +
|
||||||
|
std::string(property.c_str()) + "'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return continueOnFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
return continueOnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const typename AdapterType::Object &object;
|
||||||
|
const std::vector<std::string> &context;
|
||||||
|
bool continueOnSuccess;
|
||||||
|
bool continueOnFailure;
|
||||||
|
ValidationResults * const results;
|
||||||
|
bool * const validated;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Functor to validate property-based dependencies
|
* @brief Functor to validate property-based dependencies
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user