Skip to content

Commit

Permalink
Merge pull request #5905 from isaacvando/add-str-contains
Browse files Browse the repository at this point in the history
Add Str.contains to builtins
  • Loading branch information
bhansconnect committed Oct 14, 2023
2 parents 1c37d8a + 3df2ace commit 23624ac
Show file tree
Hide file tree
Showing 19 changed files with 297 additions and 223 deletions.
13 changes: 13 additions & 0 deletions crates/compiler/builtins/roc/Str.roc
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ interface Str
withCapacity,
withPrefix,
graphemes,
contains,
]
imports [
Bool.{ Bool, Eq },
Expand Down Expand Up @@ -995,3 +996,15 @@ strToNumHelp = \string ->
## ```
withPrefix : Str, Str -> Str
withPrefix = \str, prefix -> Str.concat prefix str

## Determines whether or not the first Str contains the second.
## ```
## expect Str.contains "foobarbaz" "bar"
## expect !(Str.contains "apple" "orange")
## expect Str.contains "anything" ""
## ```
contains : Str, Str -> Bool
contains = \haystack, needle ->
when firstMatch haystack needle is
Some _index -> Bool.true
None -> Bool.false
1 change: 1 addition & 0 deletions crates/compiler/module/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,7 @@ define_builtins! {
56 STR_IS_VALID_SCALAR: "isValidScalar"
57 STR_RELEASE_EXCESS_CAPACITY: "releaseExcessCapacity"
58 STR_WALK_UTF8: "walkUtf8"
59 STR_CONTAINS: "contains"
}
6 LIST: "List" => {
0 LIST_LIST: "List" exposed_apply_type=true // the List.List type alias
Expand Down
60 changes: 60 additions & 0 deletions crates/compiler/test_gen/src/gen_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2144,3 +2144,63 @@ fn release_excess_capacity_empty() {
|value: RocStr| (value.capacity(), value)
);
}

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_contains_positive() {
assert_evals_to!(
r#"
Str.contains "foobarbaz" "bar"
"#,
true,
bool
);
}

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_contains_negative() {
assert_evals_to!(
r#"
Str.contains "apple" "orange"
"#,
false,
bool
);
}

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_contains_empty_positive() {
assert_evals_to!(
r#"
Str.contains "anything" ""
"#,
true,
bool
);
}

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_contains_empty_negative() {
assert_evals_to!(
r#"
Str.contains "" "anything"
"#,
false,
bool
);
}

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_contains_self() {
assert_evals_to!(
r#"
Str.contains "self" "self"
"#,
true,
bool
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ procedure Num.51 (#Attr.2, #Attr.3):
ret Num.291;

procedure Str.3 (#Attr.2, #Attr.3):
let Str.291 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.291;
let Str.294 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.294;

procedure Test.1 (Test.5):
ret Test.5;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,38 +345,38 @@ procedure Num.94 (#Attr.2, #Attr.3):
ret Num.311;

procedure Str.12 (#Attr.2):
let Str.307 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.307;
let Str.310 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.310;

procedure Str.4 (#Attr.2, #Attr.3):
let Str.310 : Str = lowlevel StrJoinWith #Attr.2 #Attr.3;
ret Str.310;
let Str.313 : Str = lowlevel StrJoinWith #Attr.2 #Attr.3;
ret Str.313;

procedure Str.48 (#Attr.2, #Attr.3, #Attr.4):
let Str.298 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.298;
let Str.301 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.301;

procedure Str.55 (#Attr.2):
let Str.313 : List Str = lowlevel StrGraphemes #Attr.2;
ret Str.313;

procedure Str.9 (Str.79):
let Str.296 : U64 = 0i64;
let Str.297 : U64 = CallByName List.6 Str.79;
let Str.80 : {U64, Str, Int1, U8} = CallByName Str.48 Str.79 Str.296 Str.297;
let Str.293 : Int1 = StructAtIndex 2 Str.80;
if Str.293 then
let Str.295 : Str = StructAtIndex 1 Str.80;
let Str.294 : [C {U64, U8}, C Str] = TagId(1) Str.295;
ret Str.294;
let Str.316 : List Str = lowlevel StrGraphemes #Attr.2;
ret Str.316;

procedure Str.9 (Str.80):
let Str.299 : U64 = 0i64;
let Str.300 : U64 = CallByName List.6 Str.80;
let Str.81 : {U64, Str, Int1, U8} = CallByName Str.48 Str.80 Str.299 Str.300;
let Str.296 : Int1 = StructAtIndex 2 Str.81;
if Str.296 then
let Str.298 : Str = StructAtIndex 1 Str.81;
let Str.297 : [C {U64, U8}, C Str] = TagId(1) Str.298;
ret Str.297;
else
let Str.291 : U8 = StructAtIndex 3 Str.80;
let Str.292 : U64 = StructAtIndex 0 Str.80;
let #Derived_gen.58 : Str = StructAtIndex 1 Str.80;
let Str.294 : U8 = StructAtIndex 3 Str.81;
let Str.295 : U64 = StructAtIndex 0 Str.81;
let #Derived_gen.58 : Str = StructAtIndex 1 Str.81;
dec #Derived_gen.58;
let Str.290 : {U64, U8} = Struct {Str.292, Str.291};
let Str.289 : [C {U64, U8}, C Str] = TagId(0) Str.290;
ret Str.289;
let Str.293 : {U64, U8} = Struct {Str.295, Str.294};
let Str.292 : [C {U64, U8}, C Str] = TagId(0) Str.293;
ret Str.292;

procedure TotallyNotJson.100 (TotallyNotJson.850):
let TotallyNotJson.1830 : Str = "a";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,38 +288,38 @@ procedure Num.94 (#Attr.2, #Attr.3):
ret Num.301;

procedure Str.12 (#Attr.2):
let Str.300 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.300;
let Str.303 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.303;

procedure Str.4 (#Attr.2, #Attr.3):
let Str.303 : Str = lowlevel StrJoinWith #Attr.2 #Attr.3;
ret Str.303;
let Str.306 : Str = lowlevel StrJoinWith #Attr.2 #Attr.3;
ret Str.306;

procedure Str.48 (#Attr.2, #Attr.3, #Attr.4):
let Str.298 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.298;
let Str.301 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.301;

procedure Str.55 (#Attr.2):
let Str.306 : List Str = lowlevel StrGraphemes #Attr.2;
ret Str.306;

procedure Str.9 (Str.79):
let Str.296 : U64 = 0i64;
let Str.297 : U64 = CallByName List.6 Str.79;
let Str.80 : {U64, Str, Int1, U8} = CallByName Str.48 Str.79 Str.296 Str.297;
let Str.293 : Int1 = StructAtIndex 2 Str.80;
if Str.293 then
let Str.295 : Str = StructAtIndex 1 Str.80;
let Str.294 : [C {U64, U8}, C Str] = TagId(1) Str.295;
ret Str.294;
let Str.309 : List Str = lowlevel StrGraphemes #Attr.2;
ret Str.309;

procedure Str.9 (Str.80):
let Str.299 : U64 = 0i64;
let Str.300 : U64 = CallByName List.6 Str.80;
let Str.81 : {U64, Str, Int1, U8} = CallByName Str.48 Str.80 Str.299 Str.300;
let Str.296 : Int1 = StructAtIndex 2 Str.81;
if Str.296 then
let Str.298 : Str = StructAtIndex 1 Str.81;
let Str.297 : [C {U64, U8}, C Str] = TagId(1) Str.298;
ret Str.297;
else
let Str.291 : U8 = StructAtIndex 3 Str.80;
let Str.292 : U64 = StructAtIndex 0 Str.80;
let #Derived_gen.36 : Str = StructAtIndex 1 Str.80;
let Str.294 : U8 = StructAtIndex 3 Str.81;
let Str.295 : U64 = StructAtIndex 0 Str.81;
let #Derived_gen.36 : Str = StructAtIndex 1 Str.81;
dec #Derived_gen.36;
let Str.290 : {U64, U8} = Struct {Str.292, Str.291};
let Str.289 : [C {U64, U8}, C Str] = TagId(0) Str.290;
ret Str.289;
let Str.293 : {U64, U8} = Struct {Str.295, Str.294};
let Str.292 : [C {U64, U8}, C Str] = TagId(0) Str.293;
ret Str.292;

procedure TotallyNotJson.100 (TotallyNotJson.850):
let TotallyNotJson.1479 : Str = "a";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,38 +295,38 @@ procedure Num.94 (#Attr.2, #Attr.3):
ret Num.301;

procedure Str.12 (#Attr.2):
let Str.300 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.300;
let Str.303 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.303;

procedure Str.4 (#Attr.2, #Attr.3):
let Str.303 : Str = lowlevel StrJoinWith #Attr.2 #Attr.3;
ret Str.303;
let Str.306 : Str = lowlevel StrJoinWith #Attr.2 #Attr.3;
ret Str.306;

procedure Str.48 (#Attr.2, #Attr.3, #Attr.4):
let Str.298 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.298;
let Str.301 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.301;

procedure Str.55 (#Attr.2):
let Str.306 : List Str = lowlevel StrGraphemes #Attr.2;
ret Str.306;

procedure Str.9 (Str.79):
let Str.296 : U64 = 0i64;
let Str.297 : U64 = CallByName List.6 Str.79;
let Str.80 : {U64, Str, Int1, U8} = CallByName Str.48 Str.79 Str.296 Str.297;
let Str.293 : Int1 = StructAtIndex 2 Str.80;
if Str.293 then
let Str.295 : Str = StructAtIndex 1 Str.80;
let Str.294 : [C {U64, U8}, C Str] = TagId(1) Str.295;
ret Str.294;
let Str.309 : List Str = lowlevel StrGraphemes #Attr.2;
ret Str.309;

procedure Str.9 (Str.80):
let Str.299 : U64 = 0i64;
let Str.300 : U64 = CallByName List.6 Str.80;
let Str.81 : {U64, Str, Int1, U8} = CallByName Str.48 Str.80 Str.299 Str.300;
let Str.296 : Int1 = StructAtIndex 2 Str.81;
if Str.296 then
let Str.298 : Str = StructAtIndex 1 Str.81;
let Str.297 : [C {U64, U8}, C Str] = TagId(1) Str.298;
ret Str.297;
else
let Str.291 : U8 = StructAtIndex 3 Str.80;
let Str.292 : U64 = StructAtIndex 0 Str.80;
let #Derived_gen.40 : Str = StructAtIndex 1 Str.80;
let Str.294 : U8 = StructAtIndex 3 Str.81;
let Str.295 : U64 = StructAtIndex 0 Str.81;
let #Derived_gen.40 : Str = StructAtIndex 1 Str.81;
dec #Derived_gen.40;
let Str.290 : {U64, U8} = Struct {Str.292, Str.291};
let Str.289 : [C {U64, U8}, C Str] = TagId(0) Str.290;
ret Str.289;
let Str.293 : {U64, U8} = Struct {Str.295, Str.294};
let Str.292 : [C {U64, U8}, C Str] = TagId(0) Str.293;
ret Str.292;

procedure TotallyNotJson.100 (TotallyNotJson.850):
let TotallyNotJson.1479 : Str = "a";
Expand Down
40 changes: 20 additions & 20 deletions crates/compiler/test_mono/generated/encode_derived_string.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,30 +162,30 @@ procedure Num.94 (#Attr.2, #Attr.3):
ret Num.293;

procedure Str.12 (#Attr.2):
let Str.299 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.299;
let Str.302 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.302;

procedure Str.48 (#Attr.2, #Attr.3, #Attr.4):
let Str.298 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.298;

procedure Str.9 (Str.79):
let Str.296 : U64 = 0i64;
let Str.297 : U64 = CallByName List.6 Str.79;
let Str.80 : {U64, Str, Int1, U8} = CallByName Str.48 Str.79 Str.296 Str.297;
let Str.293 : Int1 = StructAtIndex 2 Str.80;
if Str.293 then
let Str.295 : Str = StructAtIndex 1 Str.80;
let Str.294 : [C {U64, U8}, C Str] = TagId(1) Str.295;
ret Str.294;
let Str.301 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.301;

procedure Str.9 (Str.80):
let Str.299 : U64 = 0i64;
let Str.300 : U64 = CallByName List.6 Str.80;
let Str.81 : {U64, Str, Int1, U8} = CallByName Str.48 Str.80 Str.299 Str.300;
let Str.296 : Int1 = StructAtIndex 2 Str.81;
if Str.296 then
let Str.298 : Str = StructAtIndex 1 Str.81;
let Str.297 : [C {U64, U8}, C Str] = TagId(1) Str.298;
ret Str.297;
else
let Str.291 : U8 = StructAtIndex 3 Str.80;
let Str.292 : U64 = StructAtIndex 0 Str.80;
let #Derived_gen.13 : Str = StructAtIndex 1 Str.80;
let Str.294 : U8 = StructAtIndex 3 Str.81;
let Str.295 : U64 = StructAtIndex 0 Str.81;
let #Derived_gen.13 : Str = StructAtIndex 1 Str.81;
dec #Derived_gen.13;
let Str.290 : {U64, U8} = Struct {Str.292, Str.291};
let Str.289 : [C {U64, U8}, C Str] = TagId(0) Str.290;
ret Str.289;
let Str.293 : {U64, U8} = Struct {Str.295, Str.294};
let Str.292 : [C {U64, U8}, C Str] = TagId(0) Str.293;
ret Str.292;

procedure TotallyNotJson.182 (TotallyNotJson.183, TotallyNotJson.1175, TotallyNotJson.181):
let TotallyNotJson.1178 : List U8 = CallByName TotallyNotJson.26 TotallyNotJson.181;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,30 +243,30 @@ procedure Num.94 (#Attr.2, #Attr.3):
ret Num.303;

procedure Str.12 (#Attr.2):
let Str.300 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.300;
let Str.303 : List U8 = lowlevel StrToUtf8 #Attr.2;
ret Str.303;

procedure Str.48 (#Attr.2, #Attr.3, #Attr.4):
let Str.298 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.298;

procedure Str.9 (Str.79):
let Str.296 : U64 = 0i64;
let Str.297 : U64 = CallByName List.6 Str.79;
let Str.80 : {U64, Str, Int1, U8} = CallByName Str.48 Str.79 Str.296 Str.297;
let Str.293 : Int1 = StructAtIndex 2 Str.80;
if Str.293 then
let Str.295 : Str = StructAtIndex 1 Str.80;
let Str.294 : [C {U64, U8}, C Str] = TagId(1) Str.295;
ret Str.294;
let Str.301 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;
ret Str.301;

procedure Str.9 (Str.80):
let Str.299 : U64 = 0i64;
let Str.300 : U64 = CallByName List.6 Str.80;
let Str.81 : {U64, Str, Int1, U8} = CallByName Str.48 Str.80 Str.299 Str.300;
let Str.296 : Int1 = StructAtIndex 2 Str.81;
if Str.296 then
let Str.298 : Str = StructAtIndex 1 Str.81;
let Str.297 : [C {U64, U8}, C Str] = TagId(1) Str.298;
ret Str.297;
else
let Str.291 : U8 = StructAtIndex 3 Str.80;
let Str.292 : U64 = StructAtIndex 0 Str.80;
let #Derived_gen.34 : Str = StructAtIndex 1 Str.80;
let Str.294 : U8 = StructAtIndex 3 Str.81;
let Str.295 : U64 = StructAtIndex 0 Str.81;
let #Derived_gen.34 : Str = StructAtIndex 1 Str.81;
dec #Derived_gen.34;
let Str.290 : {U64, U8} = Struct {Str.292, Str.291};
let Str.289 : [C {U64, U8}, C Str] = TagId(0) Str.290;
ret Str.289;
let Str.293 : {U64, U8} = Struct {Str.295, Str.294};
let Str.292 : [C {U64, U8}, C Str] = TagId(0) Str.293;
ret Str.292;

procedure TotallyNotJson.182 (TotallyNotJson.183, TotallyNotJson.1216, TotallyNotJson.181):
let TotallyNotJson.1219 : List U8 = CallByName TotallyNotJson.26 TotallyNotJson.181;
Expand Down
Loading

0 comments on commit 23624ac

Please sign in to comment.