1515#include < sourcemeta/core/jsonschema_unevaluated.h>
1616#include < sourcemeta/core/jsonschema_walker.h>
1717
18- #include < map> // std::map
19- #include < optional> // std::optional
20- #include < string> // std::string
18+ #include < functional> // std::function
19+ #include < map> // std::map
20+ #include < optional> // std::optional
21+ #include < string> // std::string
2122
2223// / @defgroup jsonschema JSON Schema
2324// / @brief A set of JSON Schema utilities across draft versions.
@@ -323,8 +324,8 @@ auto schema_format_compare(const JSON::String &left, const JSON::String &right)
323324
324325// / @ingroup jsonschema
325326// /
326- // / Try to turn every possible absolute reference in a schema into a relative
327- // / one . For example:
327+ // / Remove every identifer from a schema, rephrasing references (if any) as
328+ // / needed . For example:
328329// /
329330// / ```cpp
330331// / #include <sourcemeta/core/json.h>
@@ -335,32 +336,43 @@ auto schema_format_compare(const JSON::String &left, const JSON::String &right)
335336// / sourcemeta::core::parse_json(R"JSON({
336337// / "$id": "https://www.example.com/schema",
337338// / "$schema": "https://json-schema.org/draft/2020-12/schema",
338- // / "$ref": "https://www.example.com/ another",
339+ // / "$ref": "another",
339340// / })JSON");
340341// /
341- // / sourcemeta::core::relativize (schema,
342+ // / sourcemeta::core::unidentify (schema,
342343// / sourcemeta::core::schema_official_walker,
343344// / sourcemeta::core::official_resolver);
344345// /
345346// / const sourcemeta::core::JSON expected =
346347// / sourcemeta::core::parse_json(R"JSON({
347- // / "$id": "https://www.example.com/schema",
348348// / "$schema": "https://json-schema.org/draft/2020-12/schema",
349- // / "$ref": "another",
349+ // / "$ref": "https://www.example.com/ another",
350350// / })JSON");
351351// /
352352// / assert(schema == expected);
353353// / ```
354354SOURCEMETA_CORE_JSONSCHEMA_EXPORT
355- auto relativize (
355+ auto unidentify (
356356 JSON &schema, const SchemaWalker &walker, const SchemaResolver &resolver,
357- const std::optional<std::string> &default_dialect = std::nullopt ,
358- const std::optional<std::string> &default_id = std::nullopt ) -> void;
357+ const std::optional<std::string> &default_dialect = std::nullopt ) -> void;
359358
360359// / @ingroup jsonschema
361360// /
362- // / Remove every identifer from a schema, rephrasing references (if any) as
363- // / needed. For example:
361+ // / Visit every reference in a schema. The arguments are as follows:
362+ // /
363+ // / - The current subschema
364+ // / - The base URI of the current subschema
365+ // / - The reference vocabulary
366+ // / - The reference keyword name
367+ // / - The reference keyword value
368+ using SchemaVisitorReference =
369+ std::function<void (JSON &, const URI &, const JSON::String &,
370+ const JSON::String &, const JSON::String &)>;
371+
372+ // / @ingroup jsonschema
373+ // /
374+ // / A reference visitor to try to turn every possible absolute reference in a
375+ // / schema into a relative one. For example:
364376// /
365377// / ```cpp
366378// / #include <sourcemeta/core/json.h>
@@ -371,25 +383,71 @@ auto relativize(
371383// / sourcemeta::core::parse_json(R"JSON({
372384// / "$id": "https://www.example.com/schema",
373385// / "$schema": "https://json-schema.org/draft/2020-12/schema",
374- // / "$ref": "another",
386+ // / "$ref": "https://www.example.com/ another",
375387// / })JSON");
376388// /
377- // / sourcemeta::core::unidentify (schema,
389+ // / sourcemeta::core::reference_visit (schema,
378390// / sourcemeta::core::schema_official_walker,
379- // / sourcemeta::core::official_resolver);
391+ // / sourcemeta::core::official_resolver,
392+ // / sourcemeta::core::reference_visitor_relativize);
380393// /
381394// / const sourcemeta::core::JSON expected =
382395// / sourcemeta::core::parse_json(R"JSON({
396+ // / "$id": "https://www.example.com/schema",
383397// / "$schema": "https://json-schema.org/draft/2020-12/schema",
384- // / "$ref": "https://www.example.com/ another",
398+ // / "$ref": "another",
385399// / })JSON");
386400// /
387401// / assert(schema == expected);
388402// / ```
389403SOURCEMETA_CORE_JSONSCHEMA_EXPORT
390- auto unidentify (
404+ auto reference_visitor_relativize (JSON &subschema, const URI &base,
405+ const JSON::String &vocabulary,
406+ const JSON::String &keyword,
407+ const JSON::String &value) -> void;
408+
409+ // / @ingroup jsonschema
410+ // /
411+ // / A utility function to loop over every reference in a schema, allowing
412+ // / modifications to their subschemas if desired. Note that the consumer is
413+ // / responsible for not making the schema invalid. For example:
414+ // /
415+ // / ```cpp
416+ // / #include <sourcemeta/core/json.h>
417+ // / #include <sourcemeta/core/jsonschema.h>
418+ // / #include <cassert>
419+ // /
420+ // / sourcemeta::core::JSON schema =
421+ // / sourcemeta::core::parse_json(R"JSON({
422+ // / "$id": "https://www.example.com/schema",
423+ // / "$schema": "https://json-schema.org/draft/2020-12/schema",
424+ // / "$ref": "https://www.example.com/another",
425+ // / })JSON");
426+ // /
427+ // / static auto visitor(JSON &subschema,
428+ // / const URI &base,
429+ // / const JSON::String &vocabulary,
430+ // / const JSON::String &keyword,
431+ // / const JSON::String &value) -> void {
432+ // / sourcemeta::core::prettify(subschema, std::cerr);
433+ // / std::cerr << "\n";
434+ // / std::cerr << base.recompose() << "\n";
435+ // / std::cerr << vocabulary << "\n";
436+ // / std::cerr << keyword << "\n";
437+ // / std::cerr << value << "\n";
438+ // / }
439+ // /
440+ // / sourcemeta::core::reference_visit(schema,
441+ // / sourcemeta::core::schema_official_walker,
442+ // / sourcemeta::core::official_resolver,
443+ // / visitor);
444+ // / ```
445+ SOURCEMETA_CORE_JSONSCHEMA_EXPORT
446+ auto reference_visit (
391447 JSON &schema, const SchemaWalker &walker, const SchemaResolver &resolver,
392- const std::optional<std::string> &default_dialect = std::nullopt ) -> void;
448+ const SchemaVisitorReference &callback,
449+ const std::optional<std::string> &default_dialect = std::nullopt ,
450+ const std::optional<std::string> &default_id = std::nullopt ) -> void;
393451
394452} // namespace sourcemeta::core
395453
0 commit comments