hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

sub.ha (1507B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 export type end = void;
      5 
      6 fn utf8_byte_len_bounded(iter: *iterator, end: size) size = {
      7 	for (let i = 0z; i < end; i += 1) {
      8 		match (next(iter)) {
      9 		case let r: rune =>
     10 			continue;
     11 		case done =>
     12 			abort("index exceeds string length");
     13 		};
     14 	};
     15 	return iter.dec.offs;
     16 };
     17 
     18 // Returns a substring in the range [start, end - 1], where each argument is the
     19 // index of the Nth rune. If the end argument is given as [[end]], the end of
     20 // the substring is the end of the original string. The lifetime of the
     21 // substring is the same as that of the original string.
     22 //
     23 // Note that substringing runewise is not always the correct thing to do, and it
     24 // may cause unexpected linguistic errors to arise. You may want to use a
     25 // third-party Unicode module instead.
     26 export fn sub(s: str, start: size, end: (size | end) = end) str = {
     27 	let iter = iter(s);
     28 	let starti = utf8_byte_len_bounded(&iter, start);
     29 	let endi = match (end) {
     30 	case let sz: size =>
     31 		assert(start <= sz, "start is higher than end");
     32 		yield utf8_byte_len_bounded(&iter, sz - start);
     33 	case =>
     34 		yield len(s);
     35 	};
     36 	let bytes = toutf8(s);
     37 	return fromutf8_unsafe(bytes[starti..endi]);
     38 };
     39 
     40 @test fn sub() void = {
     41 	assert(sub("a string", 2) == "string");
     42 	assert(sub("a string", 2, end) == "string");
     43 	assert(sub("a string", 0, 1) == "a");
     44 	assert(sub("a string", 0, 3) == "a s");
     45 	assert(sub("a string", 2, 8) == "string");
     46 	assert(sub("a string", 4, 4) == "");
     47 };