-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement ULID.generate/0, ULID.generate/1 and ULID.decode/1 #1
Conversation
lib/ex_ulid/ulid.ex
Outdated
def decode(ulid) when byte_size(ulid) != 26 do | ||
{:error, "the ULID must be 26 characters long, got #{inspect(ulid)}"} | ||
end | ||
def decode(ulid) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def decode(<<time::bytes-size(10), id::bytes-size(16)>>)
@doc """ | ||
Generates a ULID. | ||
""" | ||
def generate do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's have generate/0
and generate/1
instead of generate_at/1
def generate do
:milli_seconds
|> :os.system_time()
|> generate()
end
def generate(time) do
# ...
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking that there might be generate(opts)
in the future and this won't work:
def generate(opts \\ [])
def generate(time, opts \\ [])
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not code for something that won't come :-)
lib/ex_ulid/ulid.ex
Outdated
def generate_at(time) do | ||
rand = :crypto.strong_rand_bytes(10) # 10 bytes = 80 bits | ||
encode_time(time) <> encode(rand, 16) | ||
rescue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I not sure about the rescue
pattern (in Erlang we almost never do this) because it obscure where the error can happen in the stack. Can we instead return {:error, "message"}
directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe something like:
case encode(time, 10) do
{:error, error} -> {:error, error}
encoded_time ->
rand = :crypto.strong_rand_bytes(10)
case encode(rand, 16) do
{:error, error} -> {:error, error}
encoded_rand -> encoded_time <> encoded_rand
end
end
It should make it clear where can the error raise.
lib/ex_ulid/ulid.ex
Outdated
end | ||
|
||
defp encode_time(time) when not is_integer(time) do | ||
raise InvalidTimeError, message: "time must be an integer, got #{inspect(time)}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following the above comment, I think this is something better handled in generate/1
when time
is passed, rather than deep down in the stack (whereas encode
itself doesn't care about max_time
and I think it shouldn't be aware of)
@sirn Please review again P.S. I need your help setting up CI for this one. There's probaly more to do than just copy & edit the Jenkinsfile. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! 🎉
Issue/Task Number: T147
Overview
Implements the main logic for
ULID.generate/0
,ULID.generate_at/1
andULID.decode/1
.Changes
Crockford
base32 encoder moduleULID.generate/0
ULID.generate_at/1
ULID.decode/1
Implementation Details
N/A
Usage
Try the instructions provided in the README.md
Impact
N/A