#pragma once #include #include #include #include #include #include #include namespace jvalidate::detail { /** * @brief An Anchor is a simple name that refers to a named location (shorhand) * in a JSON-schema. As compared to a URI - which can refer to either internal * starting-points in the active schema or external documents on disk or at an * external URL-location. * * Anchors are useful in cases where there is a complicated or long path to a * commonly used definition. Consider for example: * { "$ref": "#/properties/Column/definitions/Row" } * vs. * { "$ref": "#ColRow" } * * This can be much easier to read, or find an object when doing a quick lookup, * since editors generally don't have a "lookup this JSON-Pointer" option. * * An anchor may only be a plain-name fragment (first character is alpha or '_', * all other characters are alphanumeric, '_', '.', or '-'). * When defining an anchor using the "$anchor" or "$dynamicAnchor" tags, only * this fragment is used. When defining an anchor as part of an "$id" tag, the * form is `#`, the same as when accessing the anchor through a * "$ref". In the same document - you can reference the anchor by `#`, * just like how you can eschew the URI in a JSON-Pointer within the same doc. * * @see https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01#section-8.2.2 */ class Anchor { private: std::string content_; public: Anchor() = default; explicit Anchor(std::string_view content) : content_(content) { EXPECT_M(content.empty() || content[0] == '_' || std::isalpha(content[0]), "First character of an Anchor must be alphabetic or '_'"); EXPECT_M( std::all_of(content.begin(), content.end(), [](char c) { return std::isalnum(c) || c == '_' || c == '.' || c == '-'; }), "Illegal character(s) in anchor"); } explicit operator std::string const &() const { return content_; } bool empty() const { return content_.empty(); } friend std::ostream & operator<<(std::ostream & os, Anchor const & self) { return os << self.content_; } auto operator<=>(Anchor const & lhs) const = default; }; }