#pragma once #include #include #include #include #include #include #include namespace jvalidate::constraint { class PolyConstraint : public Constraint { private: std::vector> children_; bool match_all_; bool invert_{false}; public: template static auto AllOf(Cs &&... cs) { return std::make_unique(PolyConstraint(true, false, std::forward(cs)...)); } template static auto AnyOf(Cs &&... cs) { return std::make_unique(PolyConstraint(false, false, std::forward(cs)...)); } static auto Not(std::unique_ptr child) { return std::make_unique(PolyConstraint(false, true, std::move(child))); } Status accept(ConstraintVisitor const & visitor) const final { Status rval = Status::Noop; for (auto const & child : children_) { if (match_all_) { rval &= child->accept(visitor); } else { rval |= child->accept(visitor); } } return invert_ ? !rval : rval; } private: template PolyConstraint(bool match_all, bool invert, Cs &&... cs) : match_all_(match_all), invert_(invert) { (children_.push_back(std::forward(cs)), ...); } }; class AllOfConstraint : public SimpleConstraint { public: std::vector children; public: AllOfConstraint(std::vector const & children) : children(children) {} }; class AnyOfConstraint : public SimpleConstraint { public: std::vector children; public: AnyOfConstraint(std::vector const & children) : children(children) {} }; class EnumConstraint : public SimpleConstraint { public: std::vector> enumeration; public: EnumConstraint(std::unique_ptr && constant) { enumeration.push_back(std::move(constant)); } EnumConstraint(std::vector> && enums) : enumeration(std::move(enums)) {} }; class OneOfConstraint : public SimpleConstraint { public: std::vector children; public: OneOfConstraint(std::vector const & children) : children(children) {} }; class ConditionalConstraint : public SimpleConstraint { public: schema::Node const * if_constraint; schema::Node const * then_constraint; schema::Node const * else_constraint; public: ConditionalConstraint(schema::Node const * if_constraint, schema::Node const * then_constraint, schema::Node const * else_constraint) : if_constraint(if_constraint), then_constraint(then_constraint), else_constraint(else_constraint) {} }; class NotConstraint : public SimpleConstraint { public: schema::Node const * child; public: NotConstraint(schema::Node const * child) : child(child) {} }; class TypeConstraint : public SimpleConstraint { public: std::set types; public: TypeConstraint(adapter::Type type) : types{type} {} TypeConstraint(std::set const & types) : types(types) {} }; }