From aeac77366e9d97c0a1c8e133910bb6473b92c1a8 Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Mon, 12 May 2025 14:54:39 +0800 Subject: [PATCH 1/2] feat(string): add find_by_charcode --- string/methods.mbt | 93 +++++++++++++++++++++++++++++++++++++++++++++- string/string.mbti | 2 + 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/string/methods.mbt b/string/methods.mbt index d508de6e4a..0a16f8f715 100644 --- a/string/methods.mbt +++ b/string/methods.mbt @@ -71,6 +71,7 @@ test "find" { ///| /// Returns the offset of the first character that satisfies the given predicate. /// If no such character is found, it returns None. +#locals(pred) pub fn View::find_by(self : View, pred : (Char) -> Bool) -> Int? { for i, c in self { if pred(c) { @@ -83,8 +84,14 @@ pub fn View::find_by(self : View, pred : (Char) -> Bool) -> Int? { ///| /// Returns the offset of the first character that satisfies the given predicate. /// If no such character is found, it returns None. +#locals(pred) pub fn String::find_by(self : String, pred : (Char) -> Bool) -> Int? { - self[:].find_by(pred) + for i, c in self { + if pred(c) { + return Some(i) + } + } + None } ///| @@ -101,6 +108,90 @@ test "find_by" { inspect!("πŸ˜€πŸ˜πŸ˜‚".find_by(fn(c) { c == 'πŸ˜‚' }), content="Some(2)") } +///| +/// Find the index of the first charcode that satisfies the given predicate. +/// If no such charcode is found, it returns None. +#locals(pred) +pub fn View::find_by_charcode(self : View, pred : (Int) -> Bool) -> Int? { + for i in 0.. Bool) -> Int? { + for i in 0..= '0' && c <= '9' }), + content="None", + ) + inspect!( + "hello123".find_by_charcode(fn(c) { c >= '0' && c <= '9' }), + content="Some(5)", + ) + + // Test case sensitivity + inspect!( + "hello".find_by_charcode(fn(c) { c >= 'A' && c <= 'Z' }), + content="None", + ) + inspect!( + "Hello".find_by_charcode(fn(c) { c >= 'A' && c <= 'Z' }), + content="Some(0)", + ) + + // Test non-ASCII characters + inspect!("Ξ±Ξ²Ξ³".find_by_charcode(fn(c) { c == 'Ξ²' }), content="Some(1)") + + // Test emoji and multi-byte characters + inspect!( + "πŸ˜€πŸ˜πŸ˜‚".find_by_charcode(fn(c) { c == 0xD83D }), + content="Some(0)", + ) // First code unit of πŸ˜€ + + // Test specific code point ranges + inspect!( + "Hello, δΈ–η•Œ!".find_by_charcode(fn(c) { c > 127 }), + content="Some(7)", + ) // First non-ASCII character + + // Test with complex predicate + inspect!("a1b2c3".find_by_charcode(fn(c) { c % 2 == 0 }), content="Some(2)") // '1' has code 49 which is odd +} + ///| /// Returns the offset of the last occurrence of the given substring. If the /// substring is not found, it returns None. diff --git a/string/string.mbti b/string/string.mbti index 03eca3a83c..14a44474ee 100644 --- a/string/string.mbti +++ b/string/string.mbti @@ -94,6 +94,7 @@ impl StringView { contains_char(Self, Char) -> Bool find(Self, Self) -> Int? find_by(Self, (Char) -> Bool) -> Int? + find_by_charcode(Self, (Int) -> Bool) -> Int? fold[A](Self, init~ : A, (A, Char) -> A) -> A from_array(Array[Char]) -> Self from_iter(Iter[Char]) -> Self @@ -148,6 +149,7 @@ impl String { ends_with(String, String) -> Bool find(String, StringView) -> Int? find_by(String, (Char) -> Bool) -> Int? + find_by_charcode(String, (Int) -> Bool) -> Int? fold[A](String, init~ : A, (A, Char) -> A) -> A from_array(Array[Char]) -> String from_iter(Iter[Char]) -> String From f6d68a1be395352097db95924c7a38c177548ec9 Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Fri, 16 May 2025 10:21:32 +0800 Subject: [PATCH 2/2] fmt --- string/methods.mbt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/string/methods.mbt b/string/methods.mbt index 0a16f8f715..a809ca63cd 100644 --- a/string/methods.mbt +++ b/string/methods.mbt @@ -144,10 +144,7 @@ test "find_by_charcode" { "hello"[1:].find_by_charcode(Int::op_equal(_, 'o')), content="Some(3)", ) - inspect!( - "hello"[:4].find_by_charcode(Int::op_equal(_, 'o')), - content="None", - ) + inspect!("hello"[:4].find_by_charcode(Int::op_equal(_, 'o')), content="None") inspect!("hello".find_by_charcode(Int::op_equal(_, 'z')), content="None") // Test empty string