aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2021-07-30 20:35:57 +0100
committerLouis Pilfold <louis@lpil.uk>2021-07-30 20:35:57 +0100
commit12d91899bf20c95c491f1c7323ec9e198208ebac (patch)
treefe591676915769aeec2d1c80ac2a7a7ff43110b6
parentf37b2a7389cb7946d8a21381eb134cd3d579abc0 (diff)
downloadgleam_stdlib-12d91899bf20c95c491f1c7323ec9e198208ebac.tar.gz
gleam_stdlib-12d91899bf20c95c491f1c7323ec9e198208ebac.zip
Bit string JS funtions
-rw-r--r--CHANGELOG.md4
-rw-r--r--src/gleam/bit_string.gleam55
-rw-r--r--src/gleam_stdlib.js26
-rw-r--r--test/gleam/bit_string_test.gleam73
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
}