Skip to content

Commit 1b9ee44

Browse files
authored
Support printing SchemaFrame to standard output streams (#1574)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 82a3eb6 commit 1b9ee44

File tree

3 files changed

+677
-0
lines changed

3 files changed

+677
-0
lines changed

src/core/jsonschema/frame.cc

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,121 @@ auto SchemaFrame::to_json() const -> JSON {
393393
return root;
394394
}
395395

396+
auto operator<<(std::ostream &stream, const SchemaFrame &frame)
397+
-> std::ostream & {
398+
if (frame.locations().empty()) {
399+
return stream;
400+
}
401+
402+
for (auto iterator = frame.locations().cbegin();
403+
iterator != frame.locations().cend(); iterator++) {
404+
const auto &location{*iterator};
405+
406+
switch (location.second.type) {
407+
case SchemaFrame::LocationType::Resource:
408+
stream << "(RESOURCE)";
409+
break;
410+
case SchemaFrame::LocationType::Anchor:
411+
stream << "(ANCHOR)";
412+
break;
413+
case SchemaFrame::LocationType::Pointer:
414+
stream << "(POINTER)";
415+
break;
416+
case SchemaFrame::LocationType::Subschema:
417+
stream << "(SUBSCHEMA)";
418+
break;
419+
default:
420+
assert(false);
421+
}
422+
423+
stream << " URI: " << location.first.second << "\n";
424+
425+
if (location.first.first == SchemaReferenceType::Static) {
426+
stream << " Type : Static\n";
427+
} else {
428+
stream << " Type : Dynamic\n";
429+
}
430+
431+
stream << " Root : "
432+
<< location.second.root.value_or("<ANONYMOUS>") << "\n";
433+
434+
if (location.second.pointer.empty()) {
435+
stream << " Pointer :\n";
436+
} else {
437+
stream << " Pointer : ";
438+
sourcemeta::core::stringify(location.second.pointer, stream);
439+
stream << "\n";
440+
}
441+
442+
stream << " Base : " << location.second.base << "\n";
443+
444+
if (location.second.relative_pointer.empty()) {
445+
stream << " Relative Pointer :\n";
446+
} else {
447+
stream << " Relative Pointer : ";
448+
sourcemeta::core::stringify(location.second.relative_pointer, stream);
449+
stream << "\n";
450+
}
451+
452+
stream << " Dialect : " << location.second.dialect << "\n";
453+
stream << " Base Dialect : " << location.second.base_dialect
454+
<< "\n";
455+
456+
if (location.second.parent.has_value()) {
457+
if (location.second.parent.value().empty()) {
458+
stream << " Parent :\n";
459+
} else {
460+
stream << " Parent : ";
461+
sourcemeta::core::stringify(location.second.parent.value(), stream);
462+
stream << "\n";
463+
}
464+
} else {
465+
stream << " Parent : <NONE>\n";
466+
}
467+
468+
const auto &instance_locations{frame.instance_locations(location.second)};
469+
if (!instance_locations.empty()) {
470+
for (const auto &instance_location : instance_locations) {
471+
if (instance_location.empty()) {
472+
stream << " Instance Location :\n";
473+
} else {
474+
stream << " Instance Location : ";
475+
sourcemeta::core::stringify(instance_location, stream);
476+
stream << "\n";
477+
}
478+
}
479+
}
480+
481+
if (std::next(iterator) != frame.locations().cend()) {
482+
stream << "\n";
483+
}
484+
}
485+
486+
for (auto iterator = frame.references().cbegin();
487+
iterator != frame.references().cend(); iterator++) {
488+
stream << "\n";
489+
const auto &reference{*iterator};
490+
stream << "(REFERENCE) ORIGIN: ";
491+
sourcemeta::core::stringify(reference.first.second, stream);
492+
stream << "\n";
493+
494+
if (reference.first.first == SchemaReferenceType::Static) {
495+
stream << " Type : Static\n";
496+
} else {
497+
stream << " Type : Dynamic\n";
498+
}
499+
500+
stream << " Destination : " << reference.second.destination
501+
<< "\n";
502+
stream << " - (w/o fragment) : "
503+
<< reference.second.base.value_or("<NONE>") << "\n";
504+
stream << " - (fragment) : "
505+
<< reference.second.fragment.value_or("<NONE>") << "\n";
506+
}
507+
508+
return stream;
509+
}
510+
396511
auto SchemaFrame::analyse(const JSON &schema, const SchemaWalker &walker,
397512
const SchemaResolver &resolver,
398513
const std::optional<std::string> &default_dialect,

src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <functional> // std::reference_wrapper
1717
#include <map> // std::map
1818
#include <optional> // std::optional
19+
#include <ostream> // std::ostream
1920
#include <string> // std::string
2021
#include <tuple> // std::tuple
2122
#include <unordered_set> // std::set
@@ -240,6 +241,12 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame {
240241
#endif
241242
};
242243

244+
/// @ingroup jsonschema
245+
/// Pretty print the contents of a schema frame
246+
SOURCEMETA_CORE_JSONSCHEMA_EXPORT
247+
auto operator<<(std::ostream &stream, const SchemaFrame &frame)
248+
-> std::ostream &;
249+
243250
// TODO: Eventually generalize this to detecting cross-keyword dependencies as
244251
// part of framing
245252

0 commit comments

Comments
 (0)