hare

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

trim.ha (4194B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use bytes;
      5 
      6 const whitespace: [_]u8 = [' ', '\n', '\t', '\r'];
      7 
      8 // Returns a string (borrowed from given input string) after trimming off of
      9 // the start of the input string the characters in the given list of runes. If
     10 // no runes are given, returns the string with leading whitespace stripped off.
     11 export fn ltrim(input: str, trim: rune...) str = {
     12 	if (len(trim) == 0) {
     13 		let input = toutf8(input);
     14 		return fromutf8_unsafe(bytes::ltrim(input, whitespace...));
     15 	};
     16 	let it = iter(input);
     17 	for :outer (let r => next(&it)) {
     18 		for (let tr .. trim) {
     19 			if (r == tr) {
     20 				continue :outer;
     21 			};
     22 		};
     23 		prev(&it);
     24 		break;
     25 	};
     26 	return fromutf8_unsafe(it.dec.src[it.dec.offs..]);
     27 };
     28 
     29 // Returns a string (borrowed from given input string) after trimming off of
     30 // the end of the input string the characters in the given list of runes. If no
     31 // runes are given, returns the string with trailing whitespace stripped off.
     32 export fn rtrim(input: str, trim: rune...) str = {
     33 	if (len(trim) == 0) {
     34 		let input = toutf8(input);
     35 		return fromutf8_unsafe(bytes::rtrim(input, whitespace...));
     36 	};
     37 	let it = riter(input);
     38 	for :outer (let r => next(&it)) {
     39 		for (let tr .. trim) {
     40 			if (r == tr) {
     41 				continue :outer;
     42 			};
     43 		};
     44 		prev(&it);
     45 		break;
     46 	};
     47 	return fromutf8_unsafe(it.dec.src[..it.dec.offs]);
     48 };
     49 
     50 // Returns a string (borrowed from given input string) after trimming off of
     51 // the both ends of the input string the characters in the given list of runes.
     52 // If no runes are given, returns the string with both leading and trailing
     53 // whitespace stripped off.
     54 export fn trim(input: str, exclude: rune...) str =
     55 	ltrim(rtrim(input, exclude...), exclude...);
     56 
     57 // Returns a string (borrowed from given input string) after trimming off the
     58 // given prefix. If the input string doesn't have the given prefix, it is
     59 // returned unmodified.
     60 export fn trimprefix(input: str, trim: str) str = {
     61 	if (!hasprefix(input, trim)) return input;
     62 	const slice = toutf8(input);
     63 	return fromutf8_unsafe(slice[len(trim)..]);
     64 };
     65 
     66 // Returns a string (borrowed from given input string) after trimming off the
     67 // given suffix. If the input string doesn't have the given suffix, it is
     68 // returned unmodified.
     69 export fn trimsuffix(input: str, trim: str) str = {
     70 	if (!hassuffix(input, trim)) return input;
     71 	const slice = toutf8(input);
     72 	return fromutf8_unsafe(slice[..len(input) - len(trim)]);
     73 };
     74 
     75 @test fn trim() void = {
     76 	assert(ltrim("") == "");
     77 	assert(ltrim("  hi") == "hi");
     78 	assert(ltrim("\t\r\n  hello") == "hello");
     79 	assert(ltrim("((()(())))())", '(', ')') == "");
     80 	assert(ltrim("abacadabra", 'a', 'b', 'c', 'd') == "ra");
     81 	assert(ltrim("𝚊𝚋𝚊𝚌𝚊𝚍𝚊𝚋𝚛𝚊", '𝚊', '𝚋', '𝚌', '𝚍') == "𝚛𝚊"); // '𝚊' = U+1D68A
     82 
     83 	assert(rtrim("") == "");
     84 	assert(rtrim("hello   ") == "hello");
     85 	assert(rtrim("hello, world\r\n\r\n") == "hello, world");
     86 	assert(rtrim("Sentimentalized sensationalism sensationalized sentimentalisms",
     87 		' ', 's', 'i', 'l', 'z', 't', 'm', 'n', 'o', 'e', 'a', 'd') == "S");
     88 	assert(rtrim("\\/\\/\\\\//\\//\\////\\/\\", '/', '\\') == "");
     89 	assert(rtrim("yellowwooddoor", 'w', 'd', 'o', 'r') == "yell");
     90 
     91 	assert(trim("") == "");
     92 	assert(trim("    ​    ") == "​");
     93 	assert(trim("mississippi", 'm', 'i', 'p', 's') == "");
     94 	assert(trim("[[][[[]]][][].[[]][]]][]]]", '[', ']') == ".");
     95 	assert(trim("AAAΑА𝖠AAAA", 'A') == "ΑА𝖠");
     96 	assert(trim("  চিত্ত যেথা ভয়শূন্য, উচ্চ যেথা শির  ") == "চিত্ত যেথা ভয়শূন্য, উচ্চ যেথা শির");
     97 	assert(trim("𝖺𝖻𝖺𝖼𝖺𝖽𝖺𝖻‌𝗋‌𝖺𝖼𝖺𝖽𝖺𝖻𝖼𝖺", '𝖺', '𝖻', '𝖼', '𝖽') == "‌𝗋‌");
     98 
     99 	assert(trimprefix("", "") == "");
    100 	assert(trimprefix("", "blablabla") == "");
    101 	assert(trimprefix("hello, world", "hello") == ", world");
    102 	assert(trimprefix("blablabla", "bla") == "blabla");
    103 
    104 	assert(trimsuffix("", "") == "");
    105 	assert(trimsuffix("", "blablabla") == "");
    106 	assert(trimsuffix("hello, world", "world") == "hello, ");
    107 	assert(trimsuffix("blablabla", "bla") == "blabla");
    108 };