commit e5f9697af728b4bf2da4900b4c1a44831bc26de1
parent f2f0ca8d0da25116c0d313bae6ae1a7603930cfa
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 10 Mar 2021 10:45:40 -0500
strings: add strings::index
Diffstat:
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/strings/index.ha b/strings/index.ha
@@ -0,0 +1,25 @@
+use bytes;
+
+// Returns the index of the first occurance of 'needle' in the 'haystack', or
+// void if not present. The index returned is the rune-wise index, not the
+// byte-wise index.
+export fn index(haystack: str, needle: (str | rune)) (size | void) = {
+ return match (needle) {
+ r: rune => index_rune(haystack, r),
+ s: str => abort(), // TODO
+ };
+};
+
+fn index_rune(s: str, r: rune) (size | void) = {
+ let iter = iter(s);
+ for (let i = 0z; true; i += 1) match (next(&iter)) {
+ n: rune => if (r == n) return i,
+ void => break,
+ };
+};
+
+@test fn index() void = {
+ assert(index("hello world", 'w') as size == 6);
+ assert(index("こんにちは", 'ち') as size == 3);
+ assert(index("こんにちは", 'q') is void);
+};
diff --git a/strings/sub.ha b/strings/sub.ha
@@ -28,10 +28,10 @@ fn utf8_byte_len_unbounded(iter: *iterator) size = {
return pos;
};
-// Returns a substring in the range [start, end - 1]. If the end argument is
-// given as [strings::end], the end of the substring is the end of the original
-// string. The lifetime of the substring is the same as that of the original
-// string.
+// Returns a substring in the range [start, end - 1], where each argument is the
+// index of the Nth rune. If the end argument is given as [strings::end], the
+// end of the substring is the end of the original string. The lifetime of the
+// substring is the same as that of the original string.
export fn sub(s: str, start: size, end: (size | end)) str = {
let iter = iter(s);
let starti = utf8_byte_len_bounded(&iter, start);