parser_context.h 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #pragma once
  2. #include <cstdlib>
  3. #include <optional>
  4. #include <string>
  5. #include <jvalidate/detail/expect.h>
  6. #include <jvalidate/detail/reference.h>
  7. #include <jvalidate/detail/vocabulary.h>
  8. #include <jvalidate/forward.h>
  9. namespace jvalidate::detail {
  10. template <Adapter A> class ReferenceManager;
  11. template <Adapter A> struct ParserContext {
  12. using Object = decltype(std::declval<A>().as_object());
  13. Schema & root;
  14. A schema;
  15. Vocabulary<A> const * vocab;
  16. ReferenceManager<A> & ref;
  17. std::optional<Object> parent = std::nullopt;
  18. Reference where;
  19. Reference dynamic_where;
  20. /**
  21. * @brief Obtain the ParserContext for an arbitrary schema location,
  22. * preserving the general context members of the root Schema, Vocabulary,
  23. * and ReferenceManager.
  24. *
  25. * @param new_schema The new schema JSON adapter
  26. * @param new_loc The json pointer to this new_schema relative to its document
  27. * root.
  28. * @param new_dyn The json pointer to this new_schema using dynamic reference
  29. * rules.
  30. * @param parent The parent of this schema, if that parent is an Object.
  31. */
  32. ParserContext rebind(A const & new_schema, Reference const & new_loc, Reference const & new_dyn,
  33. std::optional<Object> parent = std::nullopt) const {
  34. return {root, new_schema, vocab, ref, parent, new_loc, new_dyn};
  35. }
  36. /**
  37. * @brief Obtain the ParserContext for the child schema of the current
  38. * location. Will set the parent context, which is used by some constraints
  39. * like "contains" or "if".
  40. *
  41. * @param child The new child schema
  42. * @param key The object-key to the new schema
  43. */
  44. ParserContext child(A const & child, std::string const & key) const {
  45. return rebind(child, where / key, dynamic_where / key, schema.as_object());
  46. }
  47. /**
  48. * @brief Obtain the ParserContext for the child schema of the current
  49. * location. Will clear the parent schema context.
  50. *
  51. * @param child The new child schema
  52. * @param key The array-index to the new schema
  53. */
  54. ParserContext child(A const & child, size_t index) const {
  55. return rebind(child, where / index, dynamic_where / index);
  56. }
  57. /**
  58. * @brief Obtain the ParserContext for the a child schema with the same parent
  59. * as this context. Called when generating {@see ConditionalConstraint}.
  60. *
  61. * @param key The object-key to the new schema
  62. */
  63. ParserContext neighbor(std::string const & key) const {
  64. EXPECT(parent.has_value());
  65. return rebind((*parent)[key], where.parent() / key, dynamic_where.parent() / key, parent);
  66. }
  67. schema::Node const * node() const;
  68. schema::Node const * always() const;
  69. schema::Node const * fixed_schema(bool accept) const;
  70. };
  71. }