diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | gen/src/gleam@string.erl | 20 | ||||
-rw-r--r-- | gen/test/gleam@string_test.erl | 15 | ||||
-rw-r--r-- | src/gleam/string.gleam | 38 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 11 | ||||
-rw-r--r-- | test/gleam/string_test.gleam | 27 |
6 files changed, 96 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index bc60f65..fa4c5bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- The `string` module gains `contains` and `repeat` functions. - The `expect` module has been renamed to `should`. Functions in the module starting with `is_` have been changed to `be_`. - The `string.replace` and `iodata.replace` `all` arguement label has been diff --git a/gen/src/gleam@string.erl b/gen/src/gleam@string.erl index a09e7e4..d383316 100644 --- a/gen/src/gleam@string.erl +++ b/gen/src/gleam@string.erl @@ -1,7 +1,7 @@ -module(gleam@string). -compile(no_auto_import). --export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, split/2, append/2, concat/1, join/2]). +-export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, contains/2, split/2, append/2, concat/1, repeat/2, join/2]). is_empty(Str) -> Str =:= <<"">>. @@ -26,6 +26,12 @@ uppercase(A) -> compare(A, B) -> gleam_stdlib:compare_strings(A, B). +erl_contains(A, B) -> + gleam_stdlib:string_contains(A, B). + +contains(Haystack, Needle) -> + erl_contains(Haystack, Needle). + split(X, Substring) -> gleam@list:map( gleam@iodata:split(gleam@iodata:new(X), Substring), @@ -40,6 +46,18 @@ append(First, Second) -> concat(Strings) -> gleam@iodata:to_string(gleam@iodata:from_strings(Strings)). +repeat_help(Chunk, Result, Repeats) -> + case Repeats =< 0 of + true -> + concat(Result); + + false -> + repeat_help(Chunk, [Chunk | Result], Repeats - 1) + end. + +repeat(String, Times) -> + repeat_help(String, [<<"">>], Times). + join(Strings, Separator) -> gleam@iodata:to_string( gleam@iodata:from_strings(gleam@list:intersperse(Strings, Separator)) diff --git a/gen/test/gleam@string_test.erl b/gen/test/gleam@string_test.erl index b6708d3..15d3a4f 100644 --- a/gen/test/gleam@string_test.erl +++ b/gen/test/gleam@string_test.erl @@ -1,7 +1,7 @@ -module(gleam@string_test). -compile(no_auto_import). --export([length_test/0, lowercase_test/0, uppercase_test/0, reverse_test/0, split_test/0, replace_test/0, append_test/0, compare_test/0, concat_test/0, join_test/0]). +-export([length_test/0, lowercase_test/0, uppercase_test/0, reverse_test/0, split_test/0, replace_test/0, append_test/0, repeat_test/0, compare_test/0, contains_test/0, concat_test/0, join_test/0]). length_test() -> gleam@should:equal(gleam@string:length(<<"ß↑e̊">>), 3), @@ -39,6 +39,11 @@ append_test() -> <<"Test Me">> ). +repeat_test() -> + gleam@should:equal(gleam@string:repeat(<<"hi">>, 3), <<"hihihi">>), + gleam@should:equal(gleam@string:repeat(<<"hi">>, 0), <<"">>), + gleam@should:equal(gleam@string:repeat(<<"hi">>, -1), <<"">>). + compare_test() -> gleam@should:equal(gleam@string:compare(<<"">>, <<"">>), eq), gleam@should:equal(gleam@string:compare(<<"a">>, <<"">>), gt), @@ -46,6 +51,14 @@ compare_test() -> gleam@should:equal(gleam@string:compare(<<"A">>, <<"B">>), lt), gleam@should:equal(gleam@string:compare(<<"t">>, <<"ABC">>), gt). +contains_test() -> + gleam@should:equal(gleam@string:contains(<<"gleam">>, <<"ea">>), true), + gleam@should:equal(gleam@string:contains(<<"gleam">>, <<"x">>), false), + gleam@should:equal( + gleam@string:contains(<<"bellwether">>, <<"bell">>), + true + ). + concat_test() -> gleam@should:equal( gleam@string:concat([<<"Hello">>, <<", ">>, <<"world!">>]), diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam index 46b1a25..b278c25 100644 --- a/src/gleam/string.gleam +++ b/src/gleam/string.gleam @@ -32,15 +32,6 @@ pub fn is_empty(str: String) -> Bool { /// pub external fn length(String) -> Int = "string" "length" -/// Repeat a string `n` times. -/// -/// ## Examples -/// ```gleam -/// repeat("ha", times: 3) == "hahaha" -/// ``` -/// -// pub fn repeat(string: String, times n: Int) -> String {} - /// Reverse a string. /// /// ## Examples @@ -141,9 +132,7 @@ pub external fn compare(String, String) -> order.Order = /// ## Check for Substrings -// TODO -// TODO: Not sure about the name and labels here -/// See if the second string contains the first one. +/// Check if the first string contains the second. /// /// ## Examples /// ```gleam @@ -152,7 +141,12 @@ pub external fn compare(String, String) -> order.Order = /// contains(does: "theory", contain: "THE") == False /// ``` /// -// pub fn contains(does haystack: String, contain needle: String) -> String {} +external fn erl_contains(String, String) -> Bool = + "gleam_stdlib" "string_contains" + +pub fn contains(does haystack: String, contain needle: String) -> Bool { + erl_contains(haystack, needle) +} // TODO // TODO: Not sure about the name and labels here @@ -220,6 +214,24 @@ pub fn concat(strings: List(String)) -> String { |> iodata.to_string } +/// Repeat a string `n` times. +/// +/// ## Examples +/// ```gleam +/// repeat("ha", times: 3) == "hahaha" +/// ``` +/// +fn repeat_help(chunk: String, result: List(String), repeats: Int) -> String { + case repeats <= 0 { + True -> concat(result) + False -> repeat_help(chunk, [chunk | result], repeats - 1) + } +} + +pub fn repeat(string: String, times times: Int) -> String { + repeat_help(string, [""], times) +} + /// Join many strings together with a given separator. /// /// ## Examples diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index 1f1f652..9e6a864 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -6,7 +6,8 @@ atom_create_from_string/1, atom_to_string/1, map_get/2, iodata_append/2, iodata_prepend/2, identity/1, decode_int/1, decode_string/1, decode_bool/1, decode_float/1, decode_thunk/1, decode_atom/1, - decode_list/1, decode_field/2, decode_element/2, parse_int/1, parse_float/1, compare_strings/2]). + decode_list/1, decode_field/2, decode_element/2, parse_int/1, parse_float/1, compare_strings/2, + string_contains/2]). should_equal(Actual, Expected) -> ?assertEqual(Expected, Actual). should_not_equal(Actual, Expected) -> ?assertNotEqual(Expected, Actual). @@ -107,3 +108,11 @@ compare_strings(Lhs, Rhs) -> true -> gt end. + +string_contains(Haystack, Needle) -> + case string:find(Haystack, Needle) of + nomatch -> + false; + _ -> + true + end. diff --git a/test/gleam/string_test.gleam b/test/gleam/string_test.gleam index ae8a0e9..133bdf5 100644 --- a/test/gleam/string_test.gleam +++ b/test/gleam/string_test.gleam @@ -67,6 +67,19 @@ pub fn compare_test() { |> should.equal(_, order.Gt) } +pub fn contains_test() { + "gleam" + |> string.contains(_, "ea") + |> should.equal(_, True) + + "gleam" + |> string.contains(_, "x") + |> should.equal(_, False) + + string.contains(does: "bellwether", contain: "bell") + |> should.equal(_, True) +} + pub fn concat_test() { [ "Hello", ", ", "world!", @@ -75,6 +88,20 @@ pub fn concat_test() { |> should.equal(_, "Hello, world!") } +pub fn repeat_test() { + "hi" + |> string.repeat(_, times: 3) + |> should.equal(_, "hihihi") + + "hi" + |> string.repeat(_, 0) + |> should.equal(_, "") + + "hi" + |> string.repeat(_, -1) + |> should.equal(_, "") +} + pub fn join_test() { [ "Hello", "world!", |