Add patternProperties in schema
This commit is contained in:
parent
8366bb8975
commit
d5c2f2ec78
@ -259,6 +259,10 @@ public:
|
|||||||
BaseSchema<Encoding>(value),
|
BaseSchema<Encoding>(value),
|
||||||
properties_(),
|
properties_(),
|
||||||
additionalPropertySchema_(),
|
additionalPropertySchema_(),
|
||||||
|
#if RAPIDJSON_SCHEMA_HAS_REGEX
|
||||||
|
patternProperties_(),
|
||||||
|
patternPropertyCount_(),
|
||||||
|
#endif
|
||||||
propertyCount_(),
|
propertyCount_(),
|
||||||
requiredCount_(),
|
requiredCount_(),
|
||||||
minProperties_(),
|
minProperties_(),
|
||||||
@ -279,6 +283,31 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RAPIDJSON_SCHEMA_HAS_REGEX
|
||||||
|
typename ValueType::ConstMemberIterator patternPropretiesItr = value.FindMember("patternProperties");
|
||||||
|
if (patternPropretiesItr != value.MemberEnd()) {
|
||||||
|
const ValueType& patternProperties = patternPropretiesItr->value;
|
||||||
|
patternProperties_ = new PatternProperty[patternProperties.MemberCount()];
|
||||||
|
patternPropertyCount_ = 0;
|
||||||
|
|
||||||
|
for (typename ValueType::ConstMemberIterator propertyItr = patternProperties.MemberBegin(); propertyItr != patternProperties.MemberEnd(); ++propertyItr) {
|
||||||
|
#if RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
|
try {
|
||||||
|
patternProperties_[patternPropertyCount_].pattern = new std::basic_regex<Ch>(
|
||||||
|
propertyItr->name.GetString(),
|
||||||
|
std::size_t(propertyItr->name.GetStringLength()),
|
||||||
|
std::regex_constants::ECMAScript);
|
||||||
|
}
|
||||||
|
catch (const std::regex_error&) {
|
||||||
|
// Error
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
patternProperties_[patternPropertyCount_].schema = CreateSchema<Encoding>(propertyItr->value); // TODO: Check error
|
||||||
|
patternPropertyCount_++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Establish required after properties
|
// Establish required after properties
|
||||||
typename ValueType::ConstMemberIterator requiredItr = value.FindMember("required");
|
typename ValueType::ConstMemberIterator requiredItr = value.FindMember("required");
|
||||||
if (requiredItr != value.MemberEnd()) {
|
if (requiredItr != value.MemberEnd()) {
|
||||||
@ -372,6 +401,9 @@ public:
|
|||||||
~ObjectSchema() {
|
~ObjectSchema() {
|
||||||
delete [] properties_;
|
delete [] properties_;
|
||||||
delete additionalPropertySchema_;
|
delete additionalPropertySchema_;
|
||||||
|
#if RAPIDJSON_SCHEMA_HAS_REGEX
|
||||||
|
delete [] patternProperties_;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SchemaType GetSchemaType() const { return kObjectSchemaType; }
|
virtual SchemaType GetSchemaType() const { return kObjectSchemaType; }
|
||||||
@ -408,6 +440,22 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RAPIDJSON_SCHEMA_HAS_REGEX
|
||||||
|
if (patternProperties_) {
|
||||||
|
for (SizeType i = 0; i < patternPropertyCount_; i++) {
|
||||||
|
#if RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
|
if (patternProperties_[i].pattern) {
|
||||||
|
std::match_results<const Ch*> r;
|
||||||
|
if (std::regex_search(str, str + len, r, *patternProperties_[i].pattern)) {
|
||||||
|
context.valueSchema = patternProperties_[i].schema;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (additionalPropertySchema_) {
|
if (additionalPropertySchema_) {
|
||||||
context.valueSchema = additionalPropertySchema_;
|
context.valueSchema = additionalPropertySchema_;
|
||||||
return true;
|
return true;
|
||||||
@ -477,9 +525,28 @@ private:
|
|||||||
bool required;
|
bool required;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if RAPIDJSON_SCHEMA_HAS_REGEX
|
||||||
|
struct PatternProperty {
|
||||||
|
PatternProperty() : schema(), pattern() {}
|
||||||
|
~PatternProperty() {
|
||||||
|
delete schema;
|
||||||
|
delete pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseSchema<Encoding>* schema;
|
||||||
|
#if RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
|
std::basic_regex<Ch>* pattern;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
TypelessSchema<Encoding> typeless_;
|
TypelessSchema<Encoding> typeless_;
|
||||||
Property* properties_;
|
Property* properties_;
|
||||||
BaseSchema<Encoding>* additionalPropertySchema_;
|
BaseSchema<Encoding>* additionalPropertySchema_;
|
||||||
|
#if RAPIDJSON_SCHEMA_HAS_REGEX
|
||||||
|
PatternProperty* patternProperties_;
|
||||||
|
SizeType patternPropertyCount_;
|
||||||
|
#endif
|
||||||
SizeType propertyCount_;
|
SizeType propertyCount_;
|
||||||
SizeType requiredCount_;
|
SizeType requiredCount_;
|
||||||
SizeType minProperties_;
|
SizeType minProperties_;
|
||||||
@ -689,7 +756,7 @@ public:
|
|||||||
if (pattern_) {
|
if (pattern_) {
|
||||||
#if RAPIDJSON_SCHEMA_USE_STDREGEX
|
#if RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
std::match_results<const Ch*> r;
|
std::match_results<const Ch*> r;
|
||||||
if (!std::regex_match(str, str + length, r, *pattern_))
|
if (!std::regex_search(str, str + length, r, *pattern_))
|
||||||
return false;
|
return false;
|
||||||
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
|
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
}
|
}
|
||||||
|
@ -314,6 +314,46 @@ TEST(SchemaValidator, Object_PropertyDependencies) {
|
|||||||
VALIDATE(s, "{ \"name\": \"John Doe\", \"billing_address\": \"555 Debtor's Lane\" }", true);
|
VALIDATE(s, "{ \"name\": \"John Doe\", \"billing_address\": \"555 Debtor's Lane\" }", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Object_PatternProperties) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse(
|
||||||
|
"{"
|
||||||
|
" \"type\": \"object\","
|
||||||
|
" \"patternProperties\": {"
|
||||||
|
" \"^S_\": { \"type\": \"string\" },"
|
||||||
|
" \"^I_\": { \"type\": \"integer\" }"
|
||||||
|
" }"
|
||||||
|
"}");
|
||||||
|
Schema s(sd);
|
||||||
|
|
||||||
|
VALIDATE(s, "{ \"S_25\": \"This is a string\" }", true);
|
||||||
|
VALIDATE(s, "{ \"I_0\": 42 }", true);
|
||||||
|
VALIDATE(s, "{ \"S_0\": 42 }", false);
|
||||||
|
VALIDATE(s, "{ \"I_42\": \"This is a string\" }", false);
|
||||||
|
VALIDATE(s, "{ \"keyword\": \"value\" }", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Object_PatternProperties_AdditionalProperties) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse(
|
||||||
|
"{"
|
||||||
|
" \"type\": \"object\","
|
||||||
|
" \"properties\": {"
|
||||||
|
" \"builtin\": { \"type\": \"number\" }"
|
||||||
|
" },"
|
||||||
|
" \"patternProperties\": {"
|
||||||
|
" \"^S_\": { \"type\": \"string\" },"
|
||||||
|
" \"^I_\": { \"type\": \"integer\" }"
|
||||||
|
" },"
|
||||||
|
" \"additionalProperties\": { \"type\": \"string\" }"
|
||||||
|
"}");
|
||||||
|
Schema s(sd);
|
||||||
|
|
||||||
|
VALIDATE(s, "{ \"builtin\": 42 }", true);
|
||||||
|
VALIDATE(s, "{ \"keyword\": \"value\" }", true);
|
||||||
|
VALIDATE(s, "{ \"keyword\": 42 }", false);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(SchemaValidator, Array) {
|
TEST(SchemaValidator, Array) {
|
||||||
Document sd;
|
Document sd;
|
||||||
sd.Parse("{\"type\":\"array\"}");
|
sd.Parse("{\"type\":\"array\"}");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user