builtin: add string.runes() (#10611)

pull/10619/head
Daniel Däschle 2021-06-30 08:17:38 +02:00 committed by GitHub
parent 1e896c7020
commit 6838030ab5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 1 deletions

View File

@ -68,6 +68,21 @@ pub fn vstrlen(s &byte) int {
return unsafe { C.strlen(&char(s)) }
}
pub fn (s string) runes() []rune {
mut runes := []rune{cap: s.len}
for i := 0; i < s.len; i++ {
char_len := utf8_char_len(unsafe { s.str[i] })
if char_len > 1 {
mut r := unsafe { s[i..i + char_len] }
runes << r.utf32_code()
i += char_len - 1
} else {
runes << unsafe { s.str[i] }
}
}
return runes
}
// tos converts a C string to a V string.
// String data is reused, not copied.
[unsafe]

View File

@ -950,3 +950,13 @@ fn test_interpolation_after_quoted_variable_still_works() {
cccq := 'Replacing "$cc" with "$tt"'
assert cccq == 'Replacing "abc" with "xyz"'
}
fn test_emoji_to_runes() {
x := '👋'
assert x.runes()[0] == `👋`
}
fn test_string_to_rune() {
x := 'Hello World 👋'
assert x.runes().len == 13
}

View File

@ -3147,8 +3147,9 @@ fn (mut g Gen) expr(node ast.Expr) {
if node.val == r'\`' {
g.write("'`'")
} else {
// TODO: optimize use L-char instead of u32 when possible
if utf8_str_len(node.val) < node.val.len {
g.write("L'$node.val'")
g.write('((u32)0x$node.val.utf32_code().hex())')
} else {
g.write("'$node.val'")
}