string_adapter.h 3.7 KB

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