diff --git a/README.md b/README.md index 531bb67..9f31035 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,9 @@ pub fn main() { } ``` # Advanced Use -In case one needs to create ULIDs out of predefined constituents -(timestamp and random), or extract them: +In case one needs to create or outpur ULIDs out of +- predefined constituents (timestamp and random) +- binary representation ```gleam import gleam/erlang @@ -80,7 +81,7 @@ import gleam/list import gleam/result import gleam/string import gleam/bool -import gulid.{from_parts, from_tuple, to_parts} +import gulid.{from_parts, from_tuple, to_parts, from_bitarray, to_bitarray} pub fn main() { let ulid = @@ -103,6 +104,22 @@ pub fn main() { let same_ulid = from_tuple(#(timestamp, random)) io.println("Same ulids? " <> { bool.to_string(same_ulid == ulid) }) + + // Ulid from a binary + let assert Ok(bin_ulid) = + << + erlang.system_time(erlang.Millisecond):big-48, + int.random(9_999_999_999):big-80, + >> + |> from_bitarray + io.println("Ulid from a bitarray: ") + io.debug(bin_ulid) + + // Ulid to a bitarray + io.println("Ulid to binary: ") + bin_ulid + |> to_bitarray + |> io.debug } @external(erlang, "calendar", "system_time_to_rfc3339") diff --git a/gleam.toml b/gleam.toml index cc8be15..e2d1f47 100644 --- a/gleam.toml +++ b/gleam.toml @@ -1,5 +1,5 @@ name = "gulid" -version = "0.0.2" +version = "0.0.3" description = "ULID implementation in Gleam (Erlang target only)" licences = ["Apache-2.0"] diff --git a/src/examples/example2.gleam b/src/examples/example2.gleam index 2c1e0f1..1f63bd0 100644 --- a/src/examples/example2.gleam +++ b/src/examples/example2.gleam @@ -5,7 +5,9 @@ import gleam/io import gleam/list import gleam/result import gleam/string -import gulid.{from_parts, from_tuple, to_parts, to_string_function} +import gulid.{ + from_bitarray, from_parts, from_tuple, to_parts, to_string_function, +} pub fn main() { let to_string = to_string_function() @@ -32,6 +34,22 @@ pub fn main() { ) io.println("Same ulids? " <> { bool.to_string(same_ulid == ulid) }) + + // Ulid from a binary + let assert Ok(bin_ulid) = + << + erlang.system_time(erlang.Millisecond):big-48, + int.random(9_999_999_999):big-80, + >> + |> from_bitarray + io.println("Ulid from a bitarray: ") + io.debug(bin_ulid) + + // Ulid to a bitarray + io.println("Ulid to binary: ") + bin_ulid + |> gulid.to_bitarray + |> io.debug } @external(erlang, "calendar", "system_time_to_rfc3339") diff --git a/src/gulid.gleam b/src/gulid.gleam index 6539010..c045e46 100644 --- a/src/gulid.gleam +++ b/src/gulid.gleam @@ -62,7 +62,7 @@ pub fn to_string_function() -> fn(Ulid) -> String { // to string let assert Ok(ulid_str) = ulid - |> to_bitarray + |> to_bitarray_130bits |> encode_to_string_with_accumulator("", base32_array) ulid_str @@ -97,7 +97,7 @@ pub fn new_as_string() -> String { } /// Builds a `Ulid` value from given `BitArray`. Returns `Ok` with `Ulid` value -/// on success or `UlidError` otherwise. +/// on success or `Error(UlidError)` otherwise. pub fn from_bitarray(array: BitArray) -> Result(Ulid, UlidError) { case array { <> -> Ok(Ulid(ulid)) @@ -239,6 +239,12 @@ pub fn from_tuple(parts: #(Int, Int)) -> Ulid { from_parts(timestamp: parts.0, random: parts.1) } +/// Returns a binary representation of given `Ulid` value +pub fn to_bitarray(ulid: Ulid) -> BitArray { + let Ulid(result) = ulid + <> +} + //-- Private stuff // Crockford base32 encoding characters @@ -276,8 +282,7 @@ fn encode_to_string_with_accumulator( } } -/// Returns a binary representation of givem `Ulid` value -fn to_bitarray(ulid: Ulid) -> BitArray { - let Ulid(result) = ulid - <<0:2, result:bits>> +/// Returns a binary representation of given `Ulid` value, expanded to 130 bits +fn to_bitarray_130bits(ulid: Ulid) -> BitArray { + <<0:2, to_bitarray(ulid):bits>> } diff --git a/test/gulid_test.gleam b/test/gulid_test.gleam index 12a6a16..060d616 100644 --- a/test/gulid_test.gleam +++ b/test/gulid_test.gleam @@ -77,3 +77,19 @@ pub fn from_parts_test() { ts |> should.equal(date_time) rnd |> should.equal(random) } + +pub fn from_bitarray_success_test() { + <> + |> gulid.from_bitarray + |> should.be_ok +} + +pub fn from_bitarray_fail_test() { + <> + |> gulid.from_bitarray + |> should.be_error +} + +pub fn to_bitarray_test() { + let assert <<_:unsigned-128>> = gulid.to_bitarray(new()) +}