Skip to content

Commit 88db405

Browse files
committed
feat: provide StringView::char_code_at
1 parent a93e65c commit 88db405

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

builtin/pkg.generated.mbti

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,10 +855,12 @@ fn Bytes::of_string(String) -> Bytes
855855
fn Bytes::to_unchecked_string(Bytes, offset? : Int, length? : Int) -> String
856856

857857
#alias("_[_]")
858+
#deprecated
858859
fn StringView::at(Self, Int) -> Int
859860
fn StringView::char_length(Self) -> Int
860861
fn StringView::char_length_eq(Self, Int) -> Bool
861862
fn StringView::char_length_ge(Self, Int) -> Bool
863+
fn StringView::code_unit_at(Self, Int) -> UInt16
862864
fn StringView::contains(Self, Self) -> Bool
863865
fn StringView::contains_any(Self, chars~ : Self) -> Bool
864866
fn StringView::contains_char(Self, Char) -> Bool

builtin/stringview.mbt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,25 @@ fn StringView::make_view(str : String, start : Int, end : Int) -> StringView = "
4141
/// inspect(view[4], content="55358")
4242
/// ```
4343
#alias("_[_]")
44+
#deprecated("Use `code_unit_at` instead which returns UInt16")
4445
pub fn StringView::at(self : StringView, index : Int) -> Int {
4546
guard index >= 0 && index < self.length() else {
4647
abort("Index out of bounds")
4748
}
4849
self.str().unsafe_charcode_at(self.start() + index)
4950
}
5051
52+
///|
53+
/// Returns the UTF-16 code unit at the given index.
54+
///
55+
/// This method has O(1) complexity.
56+
pub fn StringView::code_unit_at(self : StringView, index : Int) -> UInt16 {
57+
guard index >= 0 && index < self.length() else {
58+
abort("Index out of bounds")
59+
}
60+
self.str().code_unit_at(self.start() + index)
61+
}
62+
5163
///|
5264
/// Returns the length of the view.
5365
///

builtin/stringview_test.mbt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,22 @@ test "StringView::suffixes" {
3030
.collect()
3131
@json.inspect(suffixes_no_empty, content=["a🤣b", "🤣b", "b"])
3232
}
33+
34+
///|
35+
test "code_unit_at" {
36+
let s = "Hello, 世界!😀"
37+
assert_true(s[:].code_unit_at(0) is 'H')
38+
assert_true(s[:].code_unit_at(7) is '世')
39+
assert_true(s[:].code_unit_at(8) is '界')
40+
assert_true(s[:].code_unit_at(0) is ('A'..='Z'))
41+
inspect(s[:].code_unit_at(0), content="72") // 'H'
42+
inspect(s[:].code_unit_at(7), content="19990") // '世'
43+
inspect(s[:].code_unit_at(8), content="30028") // '界'
44+
inspect(s[:].code_unit_at(10), content="55357") // High surrogate of '😀'
45+
inspect(s[:].code_unit_at(11), content="56832") // Low surrogate of '😀'
46+
let view = s[7:] // "世界!😀"
47+
inspect(view.code_unit_at(0), content="19990") // '世'
48+
inspect(view.code_unit_at(1), content="30028") // '界'
49+
inspect(view.code_unit_at(3), content="55357") // High surrogate of '😀'
50+
inspect(view.code_unit_at(4), content="56832") // Low surrogate of '😀'
51+
}

0 commit comments

Comments
 (0)