diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-07-30 20:35:57 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-07-30 20:35:57 +0100 |
commit | 12d91899bf20c95c491f1c7323ec9e198208ebac (patch) | |
tree | fe591676915769aeec2d1c80ac2a7a7ff43110b6 | |
parent | f37b2a7389cb7946d8a21381eb134cd3d579abc0 (diff) | |
download | gleam_stdlib-12d91899bf20c95c491f1c7323ec9e198208ebac.tar.gz gleam_stdlib-12d91899bf20c95c491f1c7323ec9e198208ebac.zip |
Bit string JS funtions
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | src/gleam/bit_string.gleam | 55 | ||||
-rw-r--r-- | src/gleam_stdlib.js | 26 | ||||
-rw-r--r-- | test/gleam/bit_string_test.gleam | 73 |
4 files changed, 92 insertions, 66 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d04c072..1986086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ of target specific versions in Erlang and JavaScript specific libraries. - The `map.update` function now uses `Option` rather than `Result`. - The `iterator` module gains the `fold_until` function. -- Prelude types like `Result`, `List` etc. are no longer redefined in their stdlib modules. +- The `bit_string` module loses the u32 functions in favour of bit string literals. +- Prelude types like `Result`, `List` etc. are no longer redefined in their + stdlib modules. - All modules have been updated to work when running on both Erlang and JavaScript. diff --git a/src/gleam/bit_string.gleam b/src/gleam/bit_string.gleam index fc6cf58..1d203dc 100644 --- a/src/gleam/bit_string.gleam +++ b/src/gleam/bit_string.gleam @@ -68,43 +68,54 @@ if erlang { length: Int, ) -> Result(BitString, Nil) = "gleam_stdlib" "bit_string_part_" +} - /// Converts an integer to unsigned 32 bits. - /// - /// Returns an error if integer is less than zero or equal to or larger than - /// 2^32. - /// - pub external fn int_to_u32(Int) -> Result(BitString, Nil) = - "gleam_stdlib" "bit_string_int_to_u32" - - /// Converts unsigned 32 bits to an integer. - /// - /// Returns an error if the bit string is not 32 bits in length. - /// - pub external fn int_from_u32(BitString) -> Result(Int, Nil) = - "gleam_stdlib" "bit_string_int_from_u32" +/// Tests to see whether a bit string is valid UTF-8. +/// +pub fn is_utf8(bits: BitString) -> Bool { + do_is_utf8(bits) +} - /// Tests to see whether a bit string is valid UTF-8. - /// - pub fn is_utf8(bits: BitString) -> Bool { +if erlang { + fn do_is_utf8(bits: BitString) -> Bool { case bits { <<>> -> True <<_:utf8, rest:binary>> -> is_utf8(rest) _ -> False } } +} +if javascript { + fn do_is_utf8(bits: BitString) -> Bool { + case to_string(bits) { + Ok(_) -> True + _ -> False + } + } +} + +/// Converts a bit string to a string. +/// +/// Returns an error if the bit string is invalid UTF-8 data. +/// +pub fn to_string(bits: BitString) -> Result(String, Nil) { + do_to_string(bits) +} + +if erlang { external fn unsafe_to_string(BitString) -> String = "gleam_stdlib" "identity" - /// Converts a bit string to a string. - /// - /// Returns an error if the bit string is invalid UTF-8 data. - /// - pub fn to_string(bits: BitString) -> Result(String, Nil) { + fn do_to_string(bits: BitString) -> Result(String, Nil) { case is_utf8(bits) { True -> Ok(unsafe_to_string(bits)) False -> Error(Nil) } } } + +if javascript { + external fn do_to_string(BitString) -> Result(String, Nil) = + "../gleam_stdlib.js" "bit_string_to_string" +} diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js index 085bbe6..ff0921d 100644 --- a/src/gleam_stdlib.js +++ b/src/gleam_stdlib.js @@ -8,11 +8,11 @@ function to_list(array) { return list; } -function ok(x) { +function gleam_ok(x) { return { type: "Ok", 0: x }; } -function error(x) { +function gleam_error(x) { return { type: "Error", 0: x }; } @@ -22,9 +22,9 @@ export function identity(x) { export function parse_int(value) { if (/^[-+]?(\d+)$/.test(value)) { - return ok(Number(value)); + return gleam_ok(Number(value)); } else { - return error(Nil); + return gleam_error(Nil); } } @@ -72,9 +72,9 @@ export function pop_grapheme(string) { first = string.match(/./u)?.[0]; } if (first) { - return ok([first, string.slice(first.length)]); + return gleam_ok([first, string.slice(first.length)]); } else { - return error(Nil); + return gleam_error(Nil); } } @@ -143,9 +143,9 @@ export function split_once(haystack, needle) { if (index >= 0) { let before = haystack.slice(0, index); let after = haystack.slice(index + needle.length); - return ok([before, after]); + return gleam_ok([before, after]); } else { - return error(Nil); + return gleam_error(Nil); } } @@ -189,3 +189,13 @@ export function stringify(data) { export function crash(message) { throw new Error(message); } + +export function bit_string_to_string(bit_string) { + try { + return gleam_ok( + new TextDecoder("utf-8", { fatal: true }).decode(bit_string) + ); + } catch (_error) { + return gleam_error(undefined); + } +} diff --git a/test/gleam/bit_string_test.gleam b/test/gleam/bit_string_test.gleam index 8012587..199e1cb 100644 --- a/test/gleam/bit_string_test.gleam +++ b/test/gleam/bit_string_test.gleam @@ -57,45 +57,48 @@ if erlang { |> bit_string.part(1, 6) |> should.equal(Error(Nil)) } +} - pub fn u32_test() { - let Ok(bin) = bit_string.int_to_u32(0) - should.equal(4, bit_string.byte_size(bin)) - should.equal(Ok(0), bit_string.int_from_u32(bin)) - - let Ok(bin) = bit_string.int_to_u32(4294967295) - should.equal(4, bit_string.byte_size(bin)) - should.equal(Ok(4294967295), bit_string.int_from_u32(bin)) - - should.equal( - Error(Nil), - bit_string.int_from_u32(bit_string.from_string("")), - ) - should.equal( - Error(Nil), - bit_string.int_from_u32(bit_string.from_string("12345")), - ) - } +pub fn to_string_test() { + <<>> + |> bit_string.to_string + |> should.equal(Ok("")) - pub fn to_string_test() { - <<>> - |> bit_string.to_string - |> should.equal(Ok("")) + <<"":utf8>> + |> bit_string.to_string + |> should.equal(Ok("")) - <<"":utf8>> - |> bit_string.to_string - |> should.equal(Ok("")) + <<"Hello":utf8>> + |> bit_string.to_string + |> should.equal(Ok("Hello")) - <<"Hello":utf8>> - |> bit_string.to_string - |> should.equal(Ok("Hello")) + <<"ø":utf8>> + |> bit_string.to_string + |> should.equal(Ok("ø")) - <<"ø":utf8>> - |> bit_string.to_string - |> should.equal(Ok("ø")) + <<65535>> + |> bit_string.to_string + |> should.equal(Error(Nil)) +} - <<65535:16>> - |> bit_string.to_string - |> should.equal(Error(Nil)) - } +pub fn is_utf8_test() { + <<>> + |> bit_string.is_utf8 + |> should.be_true + + <<"":utf8>> + |> bit_string.is_utf8 + |> should.be_true + + <<"Hello":utf8>> + |> bit_string.is_utf8 + |> should.be_true + + <<"ø":utf8>> + |> bit_string.is_utf8 + |> should.be_true + + <<65535>> + |> bit_string.is_utf8 + |> should.be_false } |