relative_pointer.h 967 B

12345678910111213141516171819202122232425262728293031323334353637
  1. #pragma once
  2. #include <string>
  3. #include <string_view>
  4. #include <jvalidate/detail/expect.h>
  5. #include <jvalidate/detail/pointer.h>
  6. #include <jvalidate/forward.h>
  7. namespace jvalidate::detail {
  8. class RelativePointer {
  9. public:
  10. RelativePointer(std::string_view path) {
  11. if (auto pos = path.find('/'); pos != path.npos) {
  12. pointer_ = Pointer(path.substr(pos));
  13. path.remove_suffix(path.size() - pos);
  14. } else {
  15. EXPECT_M(not path.empty() && path.back() == '#',
  16. "RelativePointer must end in a pointer, or a '#'")
  17. path.remove_suffix(1);
  18. }
  19. parent_steps_ = std::stoull(std::string(path));
  20. }
  21. template <Adapter A>
  22. std::variant<std::string, A> inspect(Pointer const & where, A const & root) const {
  23. if (pointer_) {
  24. return pointer_->walk(where.parent(parent_steps_).walk(root));
  25. }
  26. return where.parent(parent_steps_).back();
  27. }
  28. private:
  29. size_t parent_steps_;
  30. std::optional<Pointer> pointer_;
  31. };
  32. }