Skip to content

Commit

Permalink
Added to/from BitArray support
Browse files Browse the repository at this point in the history
Implemeted:
- `Ulid` creation from a `BitArray`
- `Ulid` conversion to a `BitArray`
  • Loading branch information
vtomilin committed Oct 10, 2024
1 parent a37a16f commit 55b179c
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 11 deletions.
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 =
Expand All @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
@@ -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"]
Expand Down
20 changes: 19 additions & 1 deletion src/examples/example2.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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")
Expand Down
17 changes: 11 additions & 6 deletions src/gulid.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
<<ulid:bits-128>> -> Ok(Ulid(ulid))
Expand Down Expand Up @@ -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
<<result:bits>>
}

//-- Private stuff

// Crockford base32 encoding characters
Expand Down Expand Up @@ -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>>
}
16 changes: 16 additions & 0 deletions test/gulid_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,19 @@ pub fn from_parts_test() {
ts |> should.equal(date_time)
rnd |> should.equal(random)
}

pub fn from_bitarray_success_test() {
<<int.random(99_999_999):big-128>>
|> gulid.from_bitarray
|> should.be_ok
}

pub fn from_bitarray_fail_test() {
<<int.random(99_999_999):big-130>>
|> gulid.from_bitarray
|> should.be_error
}

pub fn to_bitarray_test() {
let assert <<_:unsigned-128>> = gulid.to_bitarray(new())
}

0 comments on commit 55b179c

Please sign in to comment.