From 2247e31a23cd97f382cbfdbf72c63fdd50673fd5 Mon Sep 17 00:00:00 2001 From: Ryan Winchester Date: Sun, 31 Mar 2024 08:42:05 -0300 Subject: [PATCH] Update docs and doctests --- README.md | 8 +++--- lib/uuidv7.ex | 63 +++++++++++++++++++++++++++++++++++++++++++- mix.exs | 25 +++++++++++++++--- test/uuidv7_test.exs | 2 +- 4 files changed, 90 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b7f3db7..8543b0e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,9 @@ [![Hex.pm](https://img.shields.io/hexpm/dt/uuid_v7)](https://hex.pm/packages/uuid_v7) [![Hex.pm](https://img.shields.io/hexpm/l/uuid_v7)](https://github.com/ryanwinchester/uuidv7/blob/main/LICENSE) -UUIDv7 for Elixir and Ecto, using microseconds. +UUIDv7 for Elixir and (optionally) Ecto, using microseconds. + +There are other UUID v7 packages, but I wanted the additional clock precision. Uses the method described in **[Section 6.2](https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-14.html#name-monotonicity-and-counters), Method 3** from [this IETF Draft](https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-14.html) @@ -18,7 +20,7 @@ The package can be installed by adding `uuid_v7` to your list of dependencies in ```elixir def deps do [ - {:uuid_v7, "~> 0.2.1"} + {:uuid_v7, "~> 0.2.2"} ] end ``` @@ -35,7 +37,7 @@ iex> UUIDv7.bingenerate() ## Usage with Ecto -Use this the same way you would use `Ecto.UUID`: +Use this the same way you would use `Ecto.UUID`. For example: ```elixir defmodule MyApp.Blog.Post do diff --git a/lib/uuidv7.ex b/lib/uuidv7.ex index c03ea32..be193ee 100644 --- a/lib/uuidv7.ex +++ b/lib/uuidv7.ex @@ -1,6 +1,20 @@ defmodule UUIDv7 do @moduledoc """ - UUIDv7 for Elixir (and Ecto). + UUIDv7 for Elixir. + + Used for generating version 7 UUIDs using microseconds for increased clock + precision. + + Includes `Ecto.Type` implementations. + + ## Examples + + iex> UUIDv7.generate() + "018e90d8-06e8-7f9f-bfd7-6730ba98a51b" + + iex> UUIDv7.bingenerate() + <<1, 142, 144, 216, 6, 232, 127, 159, 191, 215, 103, 48, 186, 152, 165, 27>> + """ @typedoc """ @@ -15,12 +29,24 @@ defmodule UUIDv7 do @doc """ Generates a version 7 UUID using microseconds for increased clock precision. + + ## Example + + iex> UUIDv7.generate() + "018e90d8-06e8-7f9f-bfd7-6730ba98a51b" + """ @spec generate() :: t def generate, do: bingenerate() |> encode() @doc """ Generates a version 7 UUID in the binary format. + + ## Example + + iex> UUIDv7.bingenerate() + <<1, 142, 144, 216, 6, 232, 127, 159, 191, 215, 103, 48, 186, 152, 165, 27>> + """ @spec bingenerate() :: raw def bingenerate do @@ -29,6 +55,17 @@ defmodule UUIDv7 do @doc """ Generates a version 7 UUID from an existing microsecond timestamp. + + ## Examples + + iex> timestamp = System.system_time(:microsecond) + iex> UUIDv7.from_timestamp(timestamp) + <<1, 142, 144, 216, 6, 232, 127, 159, 191, 215, 103, 48, 186, 152, 165, 27>> + + iex> timestamp = DateTime.utc_now() + iex> UUIDv7.from_timestamp(timestamp) + <<1, 142, 144, 216, 6, 232, 127, 159, 191, 215, 103, 48, 186, 152, 165, 27>> + """ @spec from_timestamp(pos_integer() | DateTime.t()) :: raw() def from_timestamp(%DateTime{} = datetime) do @@ -48,6 +85,15 @@ defmodule UUIDv7 do <> end + @doc """ + Encode a raw UUID to the string representation. + + ## Example + + iex> UUIDv7.encode(<<1, 142, 144, 216, 6, 232, 127, 159, 191, 215, 103, 48, 186, 152, 165, 27>>) + "018e90d8-06e8-7f9f-bfd7-6730ba98a51b" + + """ @spec encode(raw) :: t def encode( < UUIDv7.decode("018e90d8-06e8-7f9f-bfd7-6730ba98a51b") + <<1, 142, 144, 216, 6, 232, 127, 159, 191, 215, 103, 48, 186, 152, 165, 27>> + + """ @spec decode(t) :: raw | :error def decode( <> = raw_uuid), do: {:ok, encode(raw_uuid)} @@ -253,6 +313,7 @@ defmodule UUIDv7 do @doc """ Same as `load/1` but raises `Ecto.ArgumentError` on invalid arguments. """ + @doc group: :ecto @spec load!(raw | any) :: t def load!(value) do case load(value) do diff --git a/mix.exs b/mix.exs index 5d930d2..2ca4ba3 100644 --- a/mix.exs +++ b/mix.exs @@ -1,19 +1,23 @@ defmodule UUIDv7.MixProject do use Mix.Project + @version "0.2.2" + @repo_url "https://github.com/ryanwinchester/uuidv7" def project do [ app: :uuid_v7, - version: "0.2.1", + version: @version, elixir: "~> 1.16", start_permanent: Mix.env() == :prod, deps: deps(), description: description(), package: package(), source_url: @repo_url, - homepage_url: @repo_url + homepage_url: @repo_url, + name: "UUIDv7", + docs: docs() ] end @@ -44,7 +48,22 @@ defmodule UUIDv7.MixProject do defp package do [ licenses: ["MIT"], - links: %{"GitHub" => @repo_url} + links: %{"GitHub" => @repo_url}, + maintainers: ["Ryan Winchester"] + ] + end + + defp docs do + [ + main: "UUIDv7", + source_url: @repo_url, + groups_for_docs: [ + Types: &(&1[:kind] == :type), + "Ecto.Type Functions": fn fun -> + fun[:group] == :ecto or fun[:name] in [:embed_as, :equal?] + end, + Functions: &(&1[:kind] == :function) + ] ] end end diff --git a/test/uuidv7_test.exs b/test/uuidv7_test.exs index b7ff57a..b243228 100644 --- a/test/uuidv7_test.exs +++ b/test/uuidv7_test.exs @@ -1,7 +1,7 @@ defmodule UUIDv7Test do use ExUnit.Case, async: true - doctest UUIDv7 + doctest UUIDv7, except: [:moduledoc, generate: 0, bingenerate: 0, from_timestamp: 1] test "generates uuid string" do assert <<_::288>> = UUIDv7.generate()