|
|
@@ -3,14 +3,20 @@
|
|
|
#include <cctype>
|
|
|
#include <cstddef>
|
|
|
#include <ctime>
|
|
|
-#include <iostream>
|
|
|
#include <string>
|
|
|
#include <unordered_map>
|
|
|
#include <utility>
|
|
|
|
|
|
+#include <jvalidate/detail/pointer.h>
|
|
|
+#include <jvalidate/detail/relative_pointer.h>
|
|
|
#include <jvalidate/forward.h>
|
|
|
|
|
|
namespace jvalidate::format::detail {
|
|
|
+struct result {
|
|
|
+ ptrdiff_t consumed;
|
|
|
+ bool valid;
|
|
|
+};
|
|
|
+
|
|
|
inline bool is_leapyear(int y) { return (y % 400) == 0 || ((y % 4) == 0 && (y % 100) != 0); }
|
|
|
|
|
|
inline bool illegal_date(int y, int m, int d) {
|
|
|
@@ -21,22 +27,22 @@ inline bool illegal_date(int y, int m, int d) {
|
|
|
return d > days[m];
|
|
|
}
|
|
|
|
|
|
-inline auto date(std::string_view dt) {
|
|
|
+inline result date(std::string_view dt) {
|
|
|
struct tm tm;
|
|
|
if (auto end = strptime(dt.data(), "%Y-%m-%d", &tm); end) {
|
|
|
if ((end - dt.data()) != 10 || illegal_date(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday)) {
|
|
|
- return std::make_pair(0L, false);
|
|
|
+ return {.consumed = 0, .valid = false};
|
|
|
}
|
|
|
- return std::make_pair(end - dt.data(), true);
|
|
|
+ return {.consumed = end - dt.data(), .valid = true};
|
|
|
}
|
|
|
- return std::make_pair(0L, false);
|
|
|
+ return {.consumed = 0L, .valid = false};
|
|
|
}
|
|
|
}
|
|
|
|
|
|
namespace jvalidate::format {
|
|
|
inline bool date(std::string_view dt) {
|
|
|
- auto [size, good] = detail::date(dt);
|
|
|
- return good && size == dt.size();
|
|
|
+ auto [consumed, valid] = detail::date(dt);
|
|
|
+ return valid && consumed == dt.size();
|
|
|
}
|
|
|
|
|
|
inline bool time(std::string_view dt) {
|
|
|
@@ -260,6 +266,13 @@ inline bool email(std::string_view em) {
|
|
|
}
|
|
|
return hostname(em);
|
|
|
}
|
|
|
+
|
|
|
+template <typename T> inline bool ctor_as_valid(std::string_view str) {
|
|
|
+ try {
|
|
|
+ [[maybe_unused]] auto _ = T(str);
|
|
|
+ return true;
|
|
|
+ } catch (std::exception const &) { return false; }
|
|
|
+}
|
|
|
}
|
|
|
|
|
|
namespace jvalidate {
|
|
|
@@ -281,8 +294,8 @@ private:
|
|
|
{"ipv6", &format::ipv6},
|
|
|
{"iri", nullptr},
|
|
|
{"iri-reference", nullptr},
|
|
|
- {"json-pointer", nullptr},
|
|
|
- {"relative-json-pointer", nullptr},
|
|
|
+ {"json-pointer", &format::ctor_as_valid<detail::Pointer>},
|
|
|
+ {"relative-json-pointer", &format::ctor_as_valid<detail::RelativePointer>},
|
|
|
/* {"regex", &detail::StdRegexEngine::is_valid}, */
|
|
|
{"time", &format::time},
|
|
|
{"uri", nullptr},
|