| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- #pragma once
- #include <string_view>
- #include <unordered_map>
- #include <unordered_set>
- #include <jvalidate/enum.h>
- #include <jvalidate/forward.h>
- namespace jvalidate::detail {
- template <Adapter A> struct ParserContext;
- template <Adapter A> class Vocabulary {
- public:
- friend class ConstraintFactory<A>;
- using pConstraint = std::unique_ptr<constraint::Constraint>;
- using MakeConstraint = std::function<pConstraint(ParserContext<A> const &)>;
- private:
- schema::Version version_;
- std::unordered_map<std::string_view, MakeConstraint> make_;
- std::unordered_set<std::string_view> permitted_;
- // TODO(samjaffe): Migrate this back to constraintsfactory
- std::unordered_set<std::string_view> keywords_{"$defs",
- "additionalItems",
- "additionalProperties",
- "allOf",
- "anyOf",
- "definitions",
- "dependencies",
- "dependentSchemas",
- "else",
- "extends",
- "if",
- "items",
- "not",
- "oneOf",
- "patternProperties",
- "prefixItems",
- "properties",
- "then",
- "unevaluatedItems",
- "unevaluatedProperties"};
- std::unordered_set<std::string_view> property_keywords_{
- "$defs", "definitions", "dependencies", "dependentSchemas", "patternProperties",
- "properties"};
- std::unordered_set<std::string_view> post_constraints_{"unevaluatedItems",
- "unevaluatedProperties"};
- public:
- Vocabulary() = default;
- Vocabulary(schema::Version version, std::unordered_map<std::string_view, MakeConstraint> make)
- : version_(version), make_(std::move(make)) {
- for (auto const & [keyword, _] : make_) {
- permitted_.emplace(keyword);
- }
- }
- void restrict(std::unordered_set<std::string> const & permitted_keywords) & {
- permitted_.clear();
- for (auto const & [keyword, _] : make_) {
- if (permitted_keywords.contains(std::string(keyword))) {
- permitted_.insert(keyword);
- }
- }
- }
- schema::Version version() const { return version_; }
- /**
- * @brief Is the given "key"word actually a keyword? As in, would
- * I expect to resolve a constraint out of it.
- */
- bool is_keyword(std::string_view word) const {
- return permitted_.contains(word) && make_.contains(word) && keywords_.contains(word);
- }
- /**
- * @brief Does the given "key"word represent a property object - that is to
- * say, an object containing some number of schemas mapped by arbitrary keys
- */
- bool is_property_keyword(std::string_view word) const {
- return is_keyword(word) && property_keywords_.contains(word);
- }
- bool is_constraint(std::string_view word) const {
- return permitted_.contains(word) && make_.contains(word) && make_.at(word);
- }
- auto constraint(std::string_view word, ParserContext<A> const & context) const {
- return std::make_pair(is_constraint(word) ? make_.at(word)(context) : nullptr,
- post_constraints_.contains(word));
- }
- };
- }
|