commit da66885288284907c25dbaec6a7f29f44213050e
parent 9d7b1e8724206aaec5c0830d7c5f5e9486ecdec3
Author: Bor Grošelj Simić <bgs@turminal.net>
Date: Tue, 2 May 2023 04:44:22 +0200
strings: add slice(), a new way to obtain a substring
Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
Diffstat:
1 file changed, 29 insertions(+), 0 deletions(-)
diff --git a/strings/iter.ha b/strings/iter.ha
@@ -69,6 +69,16 @@ export fn iterstr(iter: *iterator) str = {
return fromutf8(iter.dec.src[iter.dec.offs..])!;
};
+// Return a substring from the position of the first operator to the position of
+// the second iterator. The iterators must originate from the same string and
+// the position of the second iterator must not be before the position of the
+// first one.
+export fn slice(begin: *iterator, end: *iterator) str = {
+ assert(begin.dec.src: *[*]u8 == end.dec.src: *[*]u8
+ && begin.dec.offs <= end.dec.offs);
+ return fromutf8_unsafe(begin.dec.src[begin.dec.offs..end.dec.offs]);
+};
+
@test fn iter() void = {
let s = iter("こんにちは");
assert(prev(&s) is void);
@@ -109,3 +119,22 @@ export fn iterstr(iter: *iterator) str = {
assert(next(&s) is void);
assert(prev(&s) as rune == 'に');
};
+
+@test fn slice() void = {
+ let s = iter("こんにちは");
+ let t = s;
+ assert(len(slice(&s, &t)) == 0 && len(slice(&t, &s)) == 0);
+ for (let i = 0; i < 2; i += 1) {
+ next(&s);
+ next(&t);
+ };
+ assert(len(slice(&s, &t)) == 0 && len(slice(&t, &s)) == 0);
+ for (let i = 0; i < 3; i += 1) {
+ next(&t);
+ };
+ assert(slice(&s, &t) == "にちは");
+ for (let i = 0; i < 3; i += 1) {
+ next(&s);
+ };
+ assert(len(slice(&s, &t)) == 0 && len(slice(&t, &s)) == 0);
+};