relative_pointer.h 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #pragma once
  2. #include <ostream>
  3. #include <string>
  4. #include <string_view>
  5. #include <jvalidate/detail/expect.h>
  6. #include <jvalidate/detail/number.h>
  7. #include <jvalidate/detail/pointer.h>
  8. #include <jvalidate/forward.h>
  9. namespace jvalidate::detail {
  10. class RelativePointer {
  11. public:
  12. RelativePointer(std::string_view path) {
  13. if (path == "0") {
  14. return;
  15. }
  16. if (auto pos = path.find('/'); pos != path.npos) {
  17. pointer_ = Pointer(path.substr(pos));
  18. path.remove_suffix(path.size() - pos);
  19. } else if (path.ends_with('#')) {
  20. requests_key_ = true;
  21. path.remove_suffix(1);
  22. }
  23. parent_steps_ = from_str<size_t>(path);
  24. }
  25. template <Adapter A>
  26. std::variant<std::string, A> inspect(Pointer const & where, A const & root) const {
  27. if (requests_key_) {
  28. return where.parent(parent_steps_).back();
  29. }
  30. auto rval = where.parent(parent_steps_).walk(root);
  31. return pointer_.walk(rval);
  32. }
  33. friend std::ostream & operator<<(std::ostream & os, RelativePointer const & rel) {
  34. os << rel.parent_steps_;
  35. if (rel.requests_key_) {
  36. return os << '#';
  37. }
  38. os << rel.pointer_;
  39. return os;
  40. }
  41. private:
  42. size_t parent_steps_ = 0;
  43. bool requests_key_ = false;
  44. Pointer pointer_ = {};
  45. };
  46. }