Last active
August 29, 2015 13:56
-
-
Save caindy/8821426 to your computer and use it in GitHub Desktop.
Elixir module to create unique identifiers of specified length, with serialization to and from strings. Put here to solicit feedback on coding style/correctness, as I am new to Elixir.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Hello.Util.UUID do | |
def new(byte_count // 16) do | |
dividend = div(byte_count, 16) | |
remainder = rem(byte_count, 16) | |
cnt = case remainder do | |
r when r === 0 -> dividend | |
_ -> dividend + remainder | |
end | |
make cnt, byte_count, <<>> | |
end | |
defp make(0, byte_count, acc), do: | |
binary_part(acc, 0, byte_count) | |
defp make(cnt, byte_count, acc) do | |
u = :ossp_uuid.make :v4, :binary | |
make(cnt - 1, byte_count, acc <> u) | |
end | |
def valid?(uuid, bytes // 16) | |
def valid?(uuid, bytes) when is_binary(uuid) do | |
case uuid do | |
<<_::[size(bytes), binary]>> -> true | |
_ -> false | |
end | |
end | |
def valid?(uuid, bytes) when is_list(uuid) do | |
chars = bytes * 2 | |
{:ok, r} = Regex.compile("[A-F0-9]{#{chars}}") | |
Regex.match?(r, uuid) and length_valid?(uuid, chars) | |
end | |
defp length_valid?(uuid, chars) when is_binary(uuid), do: | |
length_valid?(bitstring_to_list(uuid), chars) | |
defp length_valid?(uuid, chars) when is_list(uuid), do: | |
length(uuid) === chars | |
def to_string(uuid) when is_binary(uuid) do | |
l = lc <<nibble::4>> inbits uuid, do: hd(integer_to_list(nibble, 16)) | |
:erlang.list_to_binary l | |
end | |
def from_string(uuid) when is_binary(uuid), do: | |
from_string(bitstring_to_list(uuid)) | |
def from_string(uuid) when is_list(uuid), do: | |
append_byte(uuid, <<>>) | |
defp append_byte([], acc), do: acc | |
defp append_byte([x,y|rest], acc), do: | |
append_byte(rest, acc <> <<list_to_integer([x, y], 16)>>) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Peter, thanks for checking this out!
So, I've been using the
if/unless/cond
for nil tests, mostly, but I agree thecase
here obscures the intent. In fact, this code was wrong. Here's the corrected version.Thanks for your feedback 😊