diff options
-rw-r--r-- | src/gleam/binary.gleam | 23 | ||||
-rw-r--r-- | src/gleam/binary_native.erl | 12 | ||||
-rw-r--r-- | test/gleam/binary_test.gleam | 42 |
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"))) +} |