string_adapter.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #pragma once
  2. #include <map>
  3. #include <stdexcept>
  4. #include <string_view>
  5. #include <vector>
  6. #include <jvalidate/adapter.h>
  7. #include <jvalidate/detail/number.h>
  8. #include <jvalidate/detail/simple_adapter.h>
  9. #include <jvalidate/enum.h>
  10. #include <jvalidate/status.h>
  11. namespace jvalidate::detail {
  12. /**
  13. * @brief An ArrayAdapter implmenetation for JSON "types" which do not support
  14. * arrays. This is for example caused when attempting to apply json schema
  15. * validation to non-json types representation, such as a some forms of
  16. * PropertyTree implementations.
  17. *
  18. * This is specifically provided for making StringAdapter compatible with the
  19. * Adapter concept.
  20. */
  21. template <typename CRTP> class UnsupportedArrayAdapter {
  22. public:
  23. size_t size() const { return 0; }
  24. CRTP operator[](size_t) const { throw std::runtime_error("stub implementation"); }
  25. std::vector<CRTP>::const_iterator begin() const { return {}; }
  26. std::vector<CRTP>::const_iterator end() const { return {}; }
  27. };
  28. /**
  29. * @brief An ObjectAdapter implmenetation for JSON "types" which do not support
  30. * objects. This is for example caused when attempting to apply json schema
  31. * validation to non-json types representation.
  32. *
  33. * This is specifically provided for making StringAdapter compatible with the
  34. * Adapter concept.
  35. */
  36. template <typename CRTP> class UnsupportedObjectAdapter {
  37. public:
  38. size_t size() const { return 0; }
  39. bool contains(std::string_view) const { return false; }
  40. CRTP operator[](std::string_view) const { throw std::runtime_error("stub implementation"); }
  41. std::map<std::string, CRTP>::const_iterator begin() const { return {}; }
  42. std::map<std::string, CRTP>::const_iterator end() const { return {}; }
  43. };
  44. /**
  45. * @brief An Adapter for strings, required for implmenting propertyNames
  46. * constraints, which are applied to the keys of a JSON object.
  47. *
  48. * Unfortunately requires a large number of stub function implementations in
  49. * order to satisfy adapter::Adapter AND Adapter concept.
  50. */
  51. class StringAdapter final : public adapter::Adapter {
  52. public:
  53. using value_type = std::string_view;
  54. StringAdapter(std::string_view value) : value_(value) {}
  55. adapter::Type type() const { return adapter::Type::String; }
  56. bool as_boolean() const { die("boolean"); }
  57. int64_t as_integer() const { die("integer"); }
  58. double as_number() const { die("number"); }
  59. std::string as_string() const { return std::string(value_); }
  60. size_t array_size() const { die("array"); }
  61. UnsupportedArrayAdapter<StringAdapter> as_array() const { die("array"); }
  62. Status apply_array(adapter::AdapterCallback const &) const { return Status::Noop; }
  63. size_t object_size() const { die("object"); }
  64. UnsupportedObjectAdapter<StringAdapter> as_object() const { die("object"); }
  65. Status apply_object(adapter::ObjectAdapterCallback const &) const { return Status::Noop; }
  66. bool equals(adapter::Adapter const & rhs, bool strict) const {
  67. if (std::optional str = rhs.maybe_string(strict)) {
  68. return str == value_;
  69. }
  70. return false;
  71. }
  72. std::unique_ptr<adapter::Const const> freeze() const final {
  73. return std::make_unique<adapter::detail::GenericConst<std::string_view>>(value_);
  74. }
  75. private:
  76. [[noreturn]] static void die(std::string expected) {
  77. throw std::runtime_error("StringAdapter is not an " + expected);
  78. }
  79. private:
  80. std::string_view value_;
  81. };
  82. }
  83. template <> struct jvalidate::adapter::AdapterTraits<std::string_view> {
  84. template <typename> using Adapter = jvalidate::detail::StringAdapter;
  85. using ConstAdapter = jvalidate::detail::StringAdapter;
  86. };