diff options
-rw-r--r-- | src/gleam/string.gleam | 19 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 1 | ||||
-rw-r--r-- | src/gleam_stdlib.mjs | 4 | ||||
-rw-r--r-- | test/gleam/string_test.gleam | 14 |
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("๐ฉ๐พโ๐ฆฐ") +} |