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,42 @@ 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 reference destination
368+ using SchemaVisitorReference = std::function<void (
369+ JSON &, const URI &, const JSON::String &, const JSON::String &, URI &)>;
370+
371+ // / @ingroup jsonschema
372+ // /
373+ // / A reference visitor to try to turn every possible absolute reference in a
374+ // / schema into a relative one. For example:
364375// /
365376// / ```cpp
366377// / #include <sourcemeta/core/json.h>
@@ -371,25 +382,70 @@ auto relativize(
371382// / sourcemeta::core::parse_json(R"JSON({
372383// / "$id": "https://www.example.com/schema",
373384// / "$schema": "https://json-schema.org/draft/2020-12/schema",
374- // / "$ref": "another",
385+ // / "$ref": "https://www.example.com/ another",
375386// / })JSON");
376387// /
377- // / sourcemeta::core::unidentify (schema,
388+ // / sourcemeta::core::reference_visit (schema,
378389// / sourcemeta::core::schema_official_walker,
379- // / sourcemeta::core::official_resolver);
390+ // / sourcemeta::core::official_resolver,
391+ // / sourcemeta::core::reference_visitor_relativize);
380392// /
381393// / const sourcemeta::core::JSON expected =
382394// / sourcemeta::core::parse_json(R"JSON({
395+ // / "$id": "https://www.example.com/schema",
383396// / "$schema": "https://json-schema.org/draft/2020-12/schema",
384- // / "$ref": "https://www.example.com/ another",
397+ // / "$ref": "another",
385398// / })JSON");
386399// /
387400// / assert(schema == expected);
388401// / ```
389402SOURCEMETA_CORE_JSONSCHEMA_EXPORT
390- auto unidentify (
403+ auto reference_visitor_relativize (JSON &subschema, const URI &base,
404+ const JSON::String &vocabulary,
405+ const JSON::String &keyword, URI &value)
406+ -> void;
407+
408+ // / @ingroup jsonschema
409+ // /
410+ // / A utility function to loop over every reference in a schema, allowing
411+ // / modifications to their subschemas if desired. Note that the consumer is
412+ // / responsible for not making the schema invalid. For example:
413+ // /
414+ // / ```cpp
415+ // / #include <sourcemeta/core/json.h>
416+ // / #include <sourcemeta/core/jsonschema.h>
417+ // /
418+ // / sourcemeta::core::JSON schema =
419+ // / sourcemeta::core::parse_json(R"JSON({
420+ // / "$id": "https://www.example.com/schema",
421+ // / "$schema": "https://json-schema.org/draft/2020-12/schema",
422+ // / "$ref": "https://www.example.com/another",
423+ // / })JSON");
424+ // /
425+ // / static auto visitor(JSON &subschema,
426+ // / const URI &base,
427+ // / const JSON::String &vocabulary,
428+ // / const JSON::String &keyword,
429+ // / URI &value) -> void {
430+ // / sourcemeta::core::prettify(subschema, std::cerr);
431+ // / std::cerr << "\n";
432+ // / std::cerr << base.recompose() << "\n";
433+ // / std::cerr << vocabulary << "\n";
434+ // / std::cerr << keyword << "\n";
435+ // / std::cerr << value.recompose() << "\n";
436+ // / }
437+ // /
438+ // / sourcemeta::core::reference_visit(schema,
439+ // / sourcemeta::core::schema_official_walker,
440+ // / sourcemeta::core::official_resolver,
441+ // / visitor);
442+ // / ```
443+ SOURCEMETA_CORE_JSONSCHEMA_EXPORT
444+ auto reference_visit (
391445 JSON &schema, const SchemaWalker &walker, const SchemaResolver &resolver,
392- const std::optional<std::string> &default_dialect = std::nullopt ) -> void;
446+ const SchemaVisitorReference &callback,
447+ const std::optional<std::string> &default_dialect = std::nullopt ,
448+ const std::optional<std::string> &default_id = std::nullopt ) -> void;
393449
394450} // namespace sourcemeta::core
395451
0 commit comments