aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Saxton <peterhsaxton@gmail.com>2020-05-28 14:15:02 +0100
committerLouis Pilfold <louis@lpil.uk>2020-05-29 13:06:51 +0100
commite69407b2e9efb230814fbf356975c22f5a826767 (patch)
tree3034c68d72de0f0a584fc5c79125cecb307d3884
parent8d08dbc56cd67261259f557248f99581561248bc (diff)
downloadgleam_stdlib-e69407b2e9efb230814fbf356975c22f5a826767.tar.gz
gleam_stdlib-e69407b2e9efb230814fbf356975c22f5a826767.zip
add a binary module
-rw-r--r--src/gleam/binary.gleam23
-rw-r--r--src/gleam/binary_native.erl12
-rw-r--r--test/gleam/binary_test.gleam42
3 files changed, 77 insertions, 0 deletions
diff --git a/src/gleam/binary.gleam b/src/gleam/binary.gleam
new file mode 100644
index 0000000..1fa54a8
--- /dev/null
+++ b/src/gleam/binary.gleam
@@ -0,0 +1,23 @@
+//// Working with raw binary data.
+//// The Binary type should be used instead of a String type when not utf8 encoded.
+
+pub external type Binary
+
+/// Convert a utf8 String type into a raw Binary type.
+pub external fn from_string(String) -> Binary =
+ "gleam_stdlib" "identity"
+
+/// Extracts the part of a binary.
+///
+/// Binary part will start at given position and continue up to specified length.
+/// A negative length can be used to extract bytes at the end of a binary:
+pub external fn part(string: Binary, position: Int, length: Int) -> Binary = "binary" "part"
+
+
+/// Returns an integer which is the number of bytes in the binary.
+pub external fn byte_size(Binary) -> Int =
+ "erlang" "byte_size"
+
+// Not sure these will be necessary with bit syntax for for now I think they are
+pub external fn int_to_u32(Int) -> Result(Binary, Nil) = "binary_native" "int_to_u32"
+pub external fn int_from_u32(Binary) -> Result(Int, Nil) = "binary_native" "int_from_u32"
diff --git a/src/gleam/binary_native.erl b/src/gleam/binary_native.erl
new file mode 100644
index 0000000..d7e774c
--- /dev/null
+++ b/src/gleam/binary_native.erl
@@ -0,0 +1,12 @@
+-module (binary_native).
+-export ([int_to_u32/1, int_from_u32/1]).
+
+int_to_u32(I) when 0 =< I, I < 4294967296 ->
+ {ok, <<I:32>>};
+int_to_u32(_) ->
+ {error, nil}.
+
+int_from_u32(<<I:32>>) ->
+ {ok, I};
+int_from_u32(_) ->
+ {error, nil}.
diff --git a/test/gleam/binary_test.gleam b/test/gleam/binary_test.gleam
new file mode 100644
index 0000000..580aff7
--- /dev/null
+++ b/test/gleam/binary_test.gleam
@@ -0,0 +1,42 @@
+import gleam/binary
+import gleam/should
+
+pub fn length_test() {
+ binary.byte_size(binary.from_string("hello"))
+ |> should.equal(5)
+
+ binary.byte_size(binary.from_string(""))
+ |> should.equal(0)
+
+}
+
+pub fn part_test() {
+ binary.from_string("hello")
+ |> binary.part(0, 5)
+ |> should.equal(binary.from_string("hello"))
+
+ binary.from_string("hello")
+ |> binary.part(0, 0)
+ |> should.equal(binary.from_string(""))
+
+ binary.from_string("hello")
+ |> binary.part(2, 2)
+ |> should.equal(binary.from_string("ll"))
+
+ binary.from_string("hello")
+ |> binary.part(5, -2)
+ |> should.equal(binary.from_string("lo"))
+}
+
+pub fn u32_test() {
+ let Ok(bin) = binary.int_to_u32(0)
+ should.equal(4, binary.byte_size(bin))
+ should.equal(Ok(0), binary.int_from_u32(bin))
+
+ let Ok(bin) = binary.int_to_u32(4294967295)
+ should.equal(4, binary.byte_size(bin))
+ should.equal(Ok(4294967295), binary.int_from_u32(bin))
+
+ should.equal(Error(Nil), binary.int_from_u32(binary.from_string("")))
+ should.equal(Error(Nil), binary.int_from_u32(binary.from_string("12345")))
+}