Преглед на файлове

Merge branch 'refactor/string-adaptor' into feat/extension-model

# Conflicts:
#	include/jvalidate/validation_visitor.h
Sam Jaffe преди 3 месеца
родител
ревизия
d0322f637e
променени са 2 файла, в които са добавени 81 реда и са изтрити 3 реда
  1. 77 0
      include/jvalidate/detail/string_adapter.h
  2. 4 3
      include/jvalidate/validation_visitor.h

+ 77 - 0
include/jvalidate/detail/string_adapter.h

@@ -0,0 +1,77 @@
+#pragma once
+
+#include <map>
+#include <stdexcept>
+#include <string_view>
+#include <vector>
+
+#include <jvalidate/adapter.h>
+#include <jvalidate/detail/number.h>
+#include <jvalidate/detail/simple_adapter.h>
+#include <jvalidate/enum.h>
+#include <jvalidate/status.h>
+
+namespace jvalidate::detail {
+template <typename CRTP> class UnsupportedArrayAdapter {
+public:
+  size_t size() const { return 0; }
+  CRTP operator[](size_t) const { throw std::runtime_error("stub implementation"); }
+  std::vector<CRTP>::const_iterator begin() const { return {}; }
+  std::vector<CRTP>::const_iterator end() const { return {}; }
+};
+
+template <typename CRTP> class UnsupportedObjectAdapter {
+public:
+  size_t size() const { return 0; }
+  bool contains(std::string_view) const { return false; }
+  CRTP operator[](std::string_view) const { throw std::runtime_error("stub implementation"); }
+  std::map<std::string, CRTP>::const_iterator begin() const { return {}; }
+  std::map<std::string, CRTP>::const_iterator end() const { return {}; }
+};
+
+class StringAdapter final : public adapter::Adapter {
+public:
+  using value_type = std::string_view;
+
+  StringAdapter(std::string_view value) : value_(value) {}
+
+  adapter::Type type() const { return adapter::Type::String; }
+  bool as_boolean() const { die("boolean"); }
+  int64_t as_integer() const { die("integer"); }
+  double as_number() const { die("number"); }
+  std::string as_string() const { return std::string(value_); }
+
+  size_t array_size() const { die("array"); }
+  UnsupportedArrayAdapter<StringAdapter> as_array() const { die("array"); }
+  Status apply_array(adapter::AdapterCallback const &) const { return Status::Noop; }
+
+  size_t object_size() const { die("object"); }
+  UnsupportedObjectAdapter<StringAdapter> as_object() const { die("object"); }
+  Status apply_object(adapter::ObjectAdapterCallback const &) const { return Status::Noop; }
+
+  bool equals(adapter::Adapter const & rhs, bool strict) const {
+    if (std::optional str = rhs.maybe_string(strict)) {
+      return str == value_;
+    }
+    return false;
+  }
+
+  std::unique_ptr<adapter::Const const> freeze() const final {
+    return std::make_unique<adapter::detail::GenericConst<std::string_view>>(value_);
+  }
+
+private:
+  [[noreturn]] static void die(std::string expected) {
+    throw std::runtime_error("StringAdapter is not an " + expected);
+  }
+
+private:
+  std::string_view value_;
+};
+
+}
+
+template <> struct jvalidate::adapter::AdapterTraits<std::string_view> {
+  template <typename> using Adapter = jvalidate::detail::StringAdapter;
+  using ConstAdapter = jvalidate::detail::StringAdapter;
+};

+ 4 - 3
include/jvalidate/validation_visitor.h

@@ -16,6 +16,7 @@
 #include <jvalidate/detail/number.h>
 #include <jvalidate/detail/pointer.h>
 #include <jvalidate/detail/scoped_state.h>
+#include <jvalidate/detail/string_adapter.h>
 #include <jvalidate/forward.h>
 #include <jvalidate/schema.h>
 #include <jvalidate/status.h>
@@ -45,8 +46,8 @@
 namespace jvalidate {
 template <RegexEngine RE> class ValidationVisitor {
 private:
-  using VisitedAnnotation = std::tuple<std::unordered_set<size_t>, std::unordered_set<std::string>>;
   JVALIDATE_TRIBOOL_TYPE(StoreResults, ForValid, ForInvalid, ForAnything);
+  using VisitedAnnotation = std::tuple<std::unordered_set<size_t>, std::unordered_set<std::string>>;
 
 private:
   detail::Pointer where_;
@@ -510,8 +511,8 @@ public:
     Status rval = Status::Accept;
     for (auto const & [key, _] : document.as_object()) {
       // TODO(samjaffe): Should we prefer a std::string adapter like valijson?
-      typename A::value_type key_json{key};
-      rval &= validate_subschema_on(cons.key_schema, A(key_json), std::string("$$key"));
+      rval &=
+          validate_subschema_on(cons.key_schema, detail::StringAdapter(key), std::string("$$key"));
     }
     return rval;
   }