aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--gen/src/gleam@string.erl20
-rw-r--r--gen/test/gleam@string_test.erl15
-rw-r--r--src/gleam/string.gleam38
-rw-r--r--src/gleam_stdlib.erl11
-rw-r--r--test/gleam/string_test.gleam27
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!",