소스 검색

fix: UTF8 support for maxLength/minLength

Sam Jaffe 1 년 전
부모
커밋
800a2a971b
3개의 변경된 파일25개의 추가작업 그리고 4개의 파일을 삭제
  1. 6 2
      Makefile
  2. 3 2
      include/jvalidate/constraint/string_constraint.h
  3. 16 0
      include/jvalidate/detail/string.h

+ 6 - 2
Makefile

@@ -7,8 +7,12 @@ CLEAN_ANSI=| sed -r 's/\x1B\[([0-9]{1,3}(;[0-9]{1,2};?)?)?[mGK]//g'
 endif
 
 CXX := clang++
-CXX_FLAGS := -Wall -Wextra -Werror -std=c++20 -isystem include/ -DJVALIDATE_USE_EXCEPTIONS
-LD_FLAGS := -L/opt/local/lib
+
+CXX_FLAGS := -Wall -Wextra -Werror -std=c++20 \
+	     -isystem include/ -I/opt/homebrew/opt/icu4c/include \
+	     -DJVALIDATE_USE_EXCEPTIONS
+
+LD_FLAGS := -L/opt/local/lib -L/opt/homebrew/opt/icu4c/lib -licuuc
 
 TEST_DIR := tests/
 INCLUDE_DIR := include/

+ 3 - 2
include/jvalidate/constraint/string_constraint.h

@@ -3,6 +3,7 @@
 #include <string>
 
 #include <jvalidate/constraint/constraint.h>
+#include <jvalidate/detail/string.h>
 #include <jvalidate/forward.h>
 
 namespace jvalidate::constraint {
@@ -13,7 +14,7 @@ private:
 public:
   MinLengthConstraint(int64_t value) : value_(value) {}
 
-  bool operator()(std::string_view arg) const { return arg.size() >= value_; }
+  bool operator()(std::string_view arg) const { return detail::length(arg) >= value_; }
 };
 
 class MaxLengthConstraint : public SimpleConstraint<MaxLengthConstraint> {
@@ -23,7 +24,7 @@ private:
 public:
   MaxLengthConstraint(int64_t value) : value_(value) {}
 
-  bool operator()(std::string_view arg) const { return arg.size() <= value_; }
+  bool operator()(std::string_view arg) const { return detail::length(arg) <= value_; }
 };
 
 class PatternConstraint : public SimpleConstraint<PatternConstraint> {

+ 16 - 0
include/jvalidate/detail/string.h

@@ -0,0 +1,16 @@
+
+#if __has_include(<unicode/std_string.h>)
+#define JVALIDATE_HAS_ICU
+#include <unicode/unistr.h>
+#endif
+
+namespace jvalidate::detail {
+inline size_t length(std::string_view arg) {
+#ifdef JVALIDATE_HAS_ICU
+  icu::UnicodeString ucs = icu::UnicodeString::fromUTF8(icu::StringPiece(arg));
+  return ucs.countChar32();
+#else
+  return arg.size();
+#endif
+}
+}