aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gleam/string.gleam19
-rw-r--r--src/gleam_stdlib.erl1
-rw-r--r--src/gleam_stdlib.mjs4
-rw-r--r--test/gleam/string_test.gleam14
4 files changed, 37 insertions, 1 deletions
diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam
index 89efb5d..b20e726 100644
--- a/src/gleam/string.gleam
+++ b/src/gleam/string.gleam
@@ -1025,3 +1025,22 @@ if erlang {
external fn do_inspect(term: anything) -> StringBuilder =
"gleam_stdlib" "inspect"
}
+
+/// Returns the number of bytes in a `String`.
+///
+/// This function runs in constant time on Erlang and in linear time on
+/// JavaScript.
+///
+pub fn byte_size(string: String) -> Int {
+ do_byte_size(string)
+}
+
+if javascript {
+ external fn do_byte_size(String) -> Int =
+ "../gleam_stdlib.mjs" "byte_size"
+}
+
+if erlang {
+ external fn do_byte_size(String) -> Int =
+ "erlang" "byte_size"
+}
diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl
index e891202..6967cf4 100644
--- a/src/gleam_stdlib.erl
+++ b/src/gleam_stdlib.erl
@@ -439,4 +439,3 @@ inspect_maybe_utf8_string(Binary, Acc) ->
float_to_string(Float) when is_float(Float) ->
erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)).
-
diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs
index a3abe68..4fd06d9 100644
--- a/src/gleam_stdlib.mjs
+++ b/src/gleam_stdlib.mjs
@@ -733,3 +733,7 @@ function try_get_field(value, field, or_else) {
return or_else();
}
}
+
+export function byte_size(string) {
+ return new TextEncoder().encode(string).length;
+}
diff --git a/test/gleam/string_test.gleam b/test/gleam/string_test.gleam
index 3f958d4..3306f0e 100644
--- a/test/gleam/string_test.gleam
+++ b/test/gleam/string_test.gleam
@@ -985,3 +985,17 @@ if erlang {
) -> List(anything) =
"gleam_stdlib_test_ffi" "improper_list_append"
}
+
+pub fn byte_size_test() {
+ let assert 0 = string.byte_size("")
+ let assert 1 = string.byte_size("a")
+ let assert 2 = string.byte_size("ab")
+ let assert 3 = string.byte_size("abc")
+
+ // Unicode graphemes. These will be multiple bytes.
+ let assert 1 = string.byte_size("a")
+ let assert 2 = string.byte_size("รค")
+ let assert 4 = string.byte_size("๐Ÿ‘ฉ")
+ let assert 8 = string.byte_size("๐Ÿ‘ฉ๐Ÿพ")
+ let assert 15 = string.byte_size("๐Ÿ‘ฉ๐Ÿพโ€๐Ÿฆฐ")
+}