#pragma once #include #include #include #include #include #include namespace jvalidate { class ValidationResult { public: template friend class ValidationVisitor; private: std::map> annotations_; public: friend std::ostream & operator<<(std::ostream & os, ValidationResult const & result) { for (auto const & [where, annotations] : result.annotations_) { if (annotations.size() == 1) { auto const & [schema_path, message] = *annotations.begin(); std::cout << where << ": " << schema_path << ": " << message << "\n"; } else { std::cout << where << "\n"; for (auto const & [schema_path, message] : annotations) { std::cout << " " << schema_path << ": " << message << "\n"; } } } return os; } bool has_annotation(detail::Pointer const & where, detail::Pointer const & schema_path) const { return annotation(where, schema_path) != nullptr; } bool has_annotation(detail::Pointer const & where) const { return annotations_.contains(where); } std::string const * annotation(detail::Pointer const & where, detail::Pointer const & schema_path) const { if (not annotations_.contains(where)) { return nullptr; } auto const & anno = annotations_.at(where); if (not anno.contains(schema_path)) { return nullptr; } return &anno.at(schema_path); } private: void annotate(ValidationResult && result) { for (auto const & [where, errors] : result.annotations_) { for (auto const & [schema_path, message] : errors) { annotations_[where][schema_path] += message; } } } void annotate(detail::Pointer const & where, detail::Pointer const & schema_path, std::string const & message) { annotations_[where][schema_path] += message; } }; }