implement Str.dropPrefix and Str.dropSuffix

This commit is contained in:
Luke Boswell 2024-08-17 17:21:37 +10:00
parent d66f581eeb
commit 4be6c5d4ce
No known key found for this signature in database
GPG Key ID: F6DB3C9DB47377B0
3 changed files with 111 additions and 0 deletions

View File

@ -367,6 +367,8 @@ module [
withCapacity,
withPrefix,
contains,
dropPrefix,
dropSuffix,
]
import Bool exposing [Bool]
@ -752,6 +754,7 @@ countUtf8Bytes : Str -> U64
## string slice that does not do bounds checking or utf-8 verification
substringUnsafe : Str, U64, U64 -> Str
# = RocStr, start, len -> RocStr
## Returns the given [Str] with each occurrence of a substring replaced.
## If the substring is not found, returns the original string.
@ -1052,3 +1055,37 @@ contains = \haystack, needle ->
when firstMatch haystack needle is
Some _index -> Bool.true
None -> Bool.false
## Drops the given prefix [Str] from the start of a [Str]
## If the prefix is not found, returns the original string.
##
## ```roc
## expect Str.dropPrefix "bar" "foo" == "bar"
## expect Str.dropPrefix "foobar" "foo" == "bar"
## ```
dropPrefix : Str, Str -> Str
dropPrefix = \haystack, prefix ->
if Str.startsWith haystack prefix then
start = Str.countUtf8Bytes prefix
len = Num.subSaturated (Str.countUtf8Bytes haystack) start
substringUnsafe haystack start len
else
haystack
## Drops the given suffix [Str] from the end of a [Str]
## If the suffix is not found, returns the original string.
##
## ```roc
## expect Str.dropSuffix "bar" "foo" == "bar"
## expect Str.dropSuffix "barfoo" "foo" == "bar"
## ```
dropSuffix : Str, Str -> Str
dropSuffix = \haystack, suffix ->
if Str.endsWith haystack suffix then
start = 0
len = Num.subSaturated (Str.countUtf8Bytes haystack) (Str.countUtf8Bytes suffix)
substringUnsafe haystack start len
else
haystack

View File

@ -1373,6 +1373,8 @@ define_builtins! {
46 STR_REPLACE_FIRST: "replaceFirst"
47 STR_REPLACE_LAST: "replaceLast"
48 STR_RELEASE_EXCESS_CAPACITY: "releaseExcessCapacity"
49 STR_DROP_PREFIX: "dropPrefix"
50 STR_DROP_SUFFIX: "dropSuffix"
}
6 LIST: "List" => {
0 LIST_LIST: "List" exposed_apply_type=true // the List.List type alias

View File

@ -1988,3 +1988,75 @@ fn str_contains_self() {
bool
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn str_drop_prefix() {
assert_evals_to!(
r#"
Str.dropPrefix "" "foo"
"#,
RocResult::ok(RocStr::from("")),
RocResult<RocStr, ()>
);
assert_evals_to!(
r#"
Str.dropPrefix "bar" "foo"
"#,
RocResult::ok(RocStr::from("bar")),
RocResult<RocStr, ()>
);
assert_evals_to!(
r#"
Str.dropPrefix "foobar" "foo"
"#,
RocResult::ok(RocStr::from("bar")),
RocResult<RocStr, ()>
);
assert_evals_to!(
r#"
Str.dropPrefix "fooBarThisIsDefinitelyAReallyLongAndNotaShortString" "foo"
"#,
RocResult::ok(RocStr::from("BarThisIsDefinitelyAReallyLongAndNotaShortString")),
RocResult<RocStr, ()>
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn str_drop_suffix() {
assert_evals_to!(
r#"
Str.dropSuffix "" "foo"
"#,
RocResult::ok(RocStr::from("")),
RocResult<RocStr, ()>
);
assert_evals_to!(
r#"
Str.dropSuffix "bar" "foo"
"#,
RocResult::ok(RocStr::from("bar")),
RocResult<RocStr, ()>
);
assert_evals_to!(
r#"
Str.dropSuffix "barfoo" "foo"
"#,
RocResult::ok(RocStr::from("bar")),
RocResult<RocStr, ()>
);
assert_evals_to!(
r#"
Str.dropSuffix "BarThisIsDefinitelyAReallyLongAndNotaShortStringfoo" "foo"
"#,
RocResult::ok(RocStr::from("BarThisIsDefinitelyAReallyLongAndNotaShortString")),
RocResult<RocStr, ()>
);
}