runes.ha (1582B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use encoding::utf8; 5 6 // Returns a slice of runes for a string in O(n). The caller must free the 7 // return value. 8 export fn torunes(s: str) []rune = { 9 let sl: []rune = []; 10 let iter = iter(s); 11 for (let r => next(&iter)) { 12 append(sl, r); 13 }; 14 return sl; 15 }; 16 17 // Returns a string from a slice of runes. The caller must free the return value. 18 export fn fromrunes(runes: []rune) str = { 19 let bytes: []u8 = []; 20 for (let r .. runes) { 21 const bs = utf8::encoderune(r); 22 append(bytes, bs...); 23 }; 24 return fromutf8_unsafe(bytes); 25 }; 26 27 @test fn fromrunes() void = { 28 const tests: [_](str, []rune) = [ 29 ("Harriet", ['H', 'a', 'r', 'r', 'i', 'e', 't']), 30 ("", []), 31 (".", ['.']), 32 ("\a\b\f\n\r\t\v", ['\a', '\b', '\f', '\n', '\r', '\t', '\v']), 33 ("Hello, world!", ['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']), 34 ("¡Hola Mundo!", ['¡', 'H', 'o', 'l', 'a', ' ', 'M', 'u', 'n', 'd', 'o', '!']), 35 ("Γειά σου Κόσμε!", ['Γ', 'ε', 'ι', 'ά', ' ', 'σ', 'ο', 'υ', ' ', 'Κ', 'ό', 'σ', 'μ', 'ε', '!']), 36 ("Привет, мир!", ['П', 'р', 'и', 'в', 'е', 'т', ',', ' ', 'м', 'и', 'р', '!']), 37 ("こんにちは世界!", ['こ', 'ん', 'に', 'ち', 'は', '世', '界', '!']), 38 ]; 39 40 for (let (string, runes) .. tests) { 41 const s = fromrunes(runes); 42 defer free(s); 43 assert(s == string); 44 45 const rs = torunes(s); 46 defer free(rs); 47 assert(len(rs) == len(runes)); 48 49 for (let j = 0z; j < len(rs); j += 1) { 50 assert(rs[j] == runes[j]); 51 }; 52 }; 53 };