1#ifndef SOURCEMETA_BLAZE_ALTERSCHEMA_TRANSFORMER_H_
2#define SOURCEMETA_BLAZE_ALTERSCHEMA_TRANSFORMER_H_
4#ifndef SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT
5#include <sourcemeta/blaze/alterschema_export.h>
8#include <sourcemeta/core/json.h>
9#include <sourcemeta/core/jsonpointer.h>
10#include <sourcemeta/core/jsonschema.h>
27namespace sourcemeta::blaze {
34class SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaTransformRule {
36 SchemaTransformRule(
const std::string_view
name,
37 const std::string_view
message);
39 virtual ~SchemaTransformRule() =
default;
41 SchemaTransformRule(
const SchemaTransformRule &) =
delete;
42 SchemaTransformRule(SchemaTransformRule &&) =
delete;
43 auto operator=(
const SchemaTransformRule &) -> SchemaTransformRule & =
delete;
44 auto operator=(SchemaTransformRule &&) -> SchemaTransformRule & =
delete;
47 auto operator==(
const SchemaTransformRule &other)
const -> bool;
50 [[nodiscard]]
auto name() const noexcept -> std::string_view;
53 [[nodiscard]] auto
message() const noexcept -> std::string_view;
57 Result(
const bool outcome) : applies{outcome} {}
58 Result(
const sourcemeta::core::Pointer &pointer)
59 : applies{
true}, locations{pointer} {
60 assert(this->locations.size() == 1);
64 requires std::same_as<typename T::value_type, sourcemeta::core::Pointer>
65 Result(T &&container) : applies{
true} {
66 auto &&input = std::forward<T>(container);
67 if constexpr (
requires { input.size(); }) {
68 locations.reserve(input.size());
71#if __cpp_lib_containers_ranges >= 202202L
72 locations.assign_range(input);
74 locations.assign(std::make_move_iterator(std::begin(input)),
75 std::make_move_iterator(std::end(input)));
79 Result(std::vector<sourcemeta::core::Pointer> &&pointers,
80 sourcemeta::core::JSON::String &&
message)
81 : applies{
true}, locations{std::move(pointers)},
82 description{std::move(
message)} {}
85 std::vector<sourcemeta::core::Pointer> locations;
86 std::optional<sourcemeta::core::JSON::String> description;
91 check(
const sourcemeta::core::JSON &schema,
92 const sourcemeta::core::JSON &root,
93 const sourcemeta::core::SchemaVocabularies &vocabularies,
94 const sourcemeta::core::SchemaWalker &walker,
95 const sourcemeta::core::SchemaResolver &resolver,
96 const sourcemeta::core::SchemaFrame &frame,
97 const sourcemeta::core::SchemaFrame::Location &location,
98 const sourcemeta::core::JSON::String &exclude_keyword)
const ->
Result;
102 [[nodiscard]]
virtual auto
104 const sourcemeta::core::Pointer &origin,
105 const sourcemeta::core::Pointer &target,
106 const sourcemeta::core::Pointer ¤t)
const
107 -> sourcemeta::core::Pointer;
111 const sourcemeta::core::JSON &schema,
const sourcemeta::core::JSON &root,
112 const sourcemeta::core::SchemaVocabularies &vocabularies,
113 const sourcemeta::core::SchemaFrame &frame,
114 const sourcemeta::core::SchemaFrame::Location &location,
115 const sourcemeta::core::SchemaWalker &walker,
116 const sourcemeta::core::SchemaResolver &resolver)
const ->
Result = 0;
121 const Result &result)
const -> void;
128#pragma warning(disable : 4251)
130 const std::string name_{};
131 const std::string message_{};
133#pragma warning(default : 4251)
142class SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaTransformer {
144 SchemaTransformer() =
default;
147 SchemaTransformer(
const SchemaTransformer &) =
delete;
148 auto operator=(
const SchemaTransformer &) -> SchemaTransformer & =
delete;
149 SchemaTransformer(SchemaTransformer &&) =
default;
150 auto operator=(SchemaTransformer &&) -> SchemaTransformer & =
default;
155 template <std::derived_from<SchemaTransformRule> T,
typename... Args>
156 auto add(Args &&...args) -> std::string_view {
157 static_assert(
requires {
typename T::mutates; });
158 static_assert(
requires {
typename T::reframe_after_transform; });
160 std::is_same_v<typename T::mutates, std::true_type> ||
161 std::is_same_v<typename T::reframe_after_transform, std::false_type>);
162 auto &entry{this->rules_.emplace_back(
163 std::make_unique<T>(std::forward<Args>(args)...),
164 std::is_same_v<typename T::mutates, std::true_type>,
165 std::is_same_v<typename T::reframe_after_transform, std::true_type>)};
166 return std::get<0>(entry)->name();
170 auto remove(
const std::string_view name) -> bool;
174 const sourcemeta::core::Pointer &,
const std::string_view,
180 using Framer = std::function<
const sourcemeta::core::SchemaFrame &(
181 const sourcemeta::core::JSON &)>;
185 apply(sourcemeta::core::JSON &schema,
186 const sourcemeta::core::SchemaWalker &walker,
187 const sourcemeta::core::SchemaResolver &resolver,
188 const Callback &callback, std::string_view default_dialect =
"",
189 std::string_view default_id =
"",
190 const sourcemeta::core::JSON::String &exclude_keyword =
"") const
191 -> std::pair<
bool, std::uint8_t>;
197 const sourcemeta::core::SchemaWalker &walker,
198 const sourcemeta::core::SchemaResolver &resolver,
200 const sourcemeta::core::JSON::String &exclude_keyword =
"") const
201 -> std::pair<
bool, std::uint8_t>;
206 check(const sourcemeta::core::JSON &schema,
207 const sourcemeta::core::SchemaWalker &walker,
208 const sourcemeta::core::SchemaResolver &resolver,
209 const
Callback &callback, std::string_view default_dialect =
"",
210 std::string_view default_id =
"",
211 const sourcemeta::core::JSON::String &exclude_keyword =
"") const
212 -> std::pair<
bool, std::uint8_t>;
217 check(const sourcemeta::core::JSON &document,
218 const sourcemeta::core::SchemaFrame &frame,
219 const sourcemeta::core::SchemaWalker &walker,
220 const sourcemeta::core::SchemaResolver &resolver,
222 const sourcemeta::core::JSON::String &exclude_keyword =
"") const
223 -> std::pair<
bool, std::uint8_t>;
225 [[nodiscard]] auto begin() const -> auto {
return this->rules_.cbegin(); }
226 [[nodiscard]]
auto end() const -> auto {
return this->rules_.cend(); }
230#pragma warning(disable : 4251)
232 std::vector<std::tuple<std::unique_ptr<SchemaTransformRule>, bool,
bool>>
235#pragma warning(default : 4251)
auto check(const sourcemeta::core::JSON &schema, const sourcemeta::core::SchemaWalker &walker, const sourcemeta::core::SchemaResolver &resolver, const Callback &callback, std::string_view default_dialect="", std::string_view default_id="", const sourcemeta::core::JSON::String &exclude_keyword="") const -> std::pair< bool, std::uint8_t >
virtual auto transform(sourcemeta::core::JSON &schema, const Result &result) const -> void
std::function< void( const sourcemeta::core::Pointer &, const std::string_view, const std::string_view, const SchemaTransformRule::Result &, const bool)> Callback
The callback that is called whenever the condition of a rule holds true.
Definition alterschema_transformer.h:173
auto check(const sourcemeta::core::JSON &schema, const sourcemeta::core::JSON &root, const sourcemeta::core::SchemaVocabularies &vocabularies, const sourcemeta::core::SchemaWalker &walker, const sourcemeta::core::SchemaResolver &resolver, const sourcemeta::core::SchemaFrame &frame, const sourcemeta::core::SchemaFrame::Location &location, const sourcemeta::core::JSON::String &exclude_keyword) const -> Result
Check if the rule applies to a schema.
auto remove(const std::string_view name) -> bool
Remove a rule from the bundle.
auto message() const noexcept -> std::string_view
Fetch the message of a rule.
virtual auto rereference(const std::string_view reference, const sourcemeta::core::Pointer &origin, const sourcemeta::core::Pointer &target, const sourcemeta::core::Pointer ¤t) const -> sourcemeta::core::Pointer
virtual auto condition(const sourcemeta::core::JSON &schema, const sourcemeta::core::JSON &root, const sourcemeta::core::SchemaVocabularies &vocabularies, const sourcemeta::core::SchemaFrame &frame, const sourcemeta::core::SchemaFrame::Location &location, const sourcemeta::core::SchemaWalker &walker, const sourcemeta::core::SchemaResolver &resolver) const -> Result=0
The rule condition.
auto operator==(const SchemaTransformRule &other) const -> bool
Compare a rule against another rule.
auto add(Args &&...args) -> std::string_view
Definition alterschema_transformer.h:156
auto apply(sourcemeta::core::JSON &schema, const sourcemeta::core::SchemaWalker &walker, const sourcemeta::core::SchemaResolver &resolver, const Callback &callback, std::string_view default_dialect="", std::string_view default_id="", const sourcemeta::core::JSON::String &exclude_keyword="") const -> std::pair< bool, std::uint8_t >
Apply the bundle of rules to a schema.
auto name() const noexcept -> std::string_view
Fetch the name of a rule.
std::function< const sourcemeta::core::SchemaFrame &( const sourcemeta::core::JSON &)> Framer
Definition alterschema_transformer.h:180