reference.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #pragma once
  2. #include <string>
  3. #include <string_view>
  4. #include <jvalidate/detail/anchor.h>
  5. #include <jvalidate/detail/expect.h>
  6. #include <jvalidate/detail/pointer.h>
  7. #include <jvalidate/uri.h>
  8. namespace jvalidate::detail {
  9. class Reference {
  10. public:
  11. Reference() = default;
  12. Reference(URI const & uri, Anchor const & anchor = {}, Pointer const & pointer = {})
  13. : uri_(uri), anchor_(anchor), pointer_(pointer) {}
  14. Reference(std::string_view ref, bool allow_anchor = true) {
  15. size_t end_of_uri = ref.find('#');
  16. uri_ = URI(ref.substr(0, end_of_uri));
  17. if (end_of_uri == std::string::npos) {
  18. return;
  19. }
  20. ref.remove_prefix(end_of_uri + 1);
  21. size_t const pointer_start = ref.find('/');
  22. anchor_ = Anchor(ref.substr(0, pointer_start));
  23. EXPECT_M(allow_anchor || anchor_.empty(), "Anchoring is not allowed in this context");
  24. ref.remove_prefix(pointer_start);
  25. pointer_ = ref;
  26. }
  27. URI const & uri() const { return uri_; }
  28. Anchor const & anchor() const { return anchor_; }
  29. Pointer const & pointer() const { return pointer_; }
  30. Reference root() const { return {uri_, anchor_}; }
  31. Reference parent() const { return {uri_, anchor_, pointer_.parent()}; }
  32. Reference & operator/=(Pointer const & relative) {
  33. pointer_ /= relative;
  34. return *this;
  35. }
  36. Reference operator/(Pointer const & relative) const { return Reference(*this) /= relative; }
  37. Reference & operator/=(std::string_view key) {
  38. pointer_ /= key;
  39. return *this;
  40. }
  41. Reference operator/(std::string_view key) const { return Reference(*this) /= key; }
  42. Reference & operator/=(size_t index) {
  43. pointer_ /= index;
  44. return *this;
  45. }
  46. Reference operator/(size_t index) const { return Reference(*this) /= index; }
  47. friend std::ostream & operator<<(std::ostream & os, Reference const & self) {
  48. return os << self.uri_ << '#' << self.anchor_ << self.pointer_;
  49. }
  50. auto operator<=>(Reference const &) const = default;
  51. private:
  52. URI uri_;
  53. Anchor anchor_;
  54. Pointer pointer_;
  55. };
  56. }