reference.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. if (pointer_start != std::string::npos) {
  25. pointer_ = ref.substr(pointer_start);
  26. }
  27. }
  28. URI const & uri() const { return uri_; }
  29. Anchor const & anchor() const { return anchor_; }
  30. Pointer const & pointer() const { return pointer_; }
  31. Reference root() const { return {uri_, anchor_}; }
  32. Reference parent() const { return {uri_, anchor_, pointer_.parent()}; }
  33. Reference & operator/=(Pointer const & relative) {
  34. pointer_ /= relative;
  35. return *this;
  36. }
  37. Reference operator/(Pointer const & relative) const { return Reference(*this) /= relative; }
  38. Reference & operator/=(std::string_view key) {
  39. pointer_ /= key;
  40. return *this;
  41. }
  42. Reference operator/(std::string_view key) const { return Reference(*this) /= key; }
  43. Reference & operator/=(size_t index) {
  44. pointer_ /= index;
  45. return *this;
  46. }
  47. Reference operator/(size_t index) const { return Reference(*this) /= index; }
  48. friend std::ostream & operator<<(std::ostream & os, Reference const & self) {
  49. return os << self.uri_ << '#' << self.anchor_ << self.pointer_;
  50. }
  51. auto operator<=>(Reference const &) const = default;
  52. private:
  53. URI uri_;
  54. Anchor anchor_;
  55. Pointer pointer_;
  56. };
  57. }