From f06f318e5a23f6725812d1de1db13be4727e038c Mon Sep 17 00:00:00 2001 From: Yaroslav Rogov Date: Thu, 26 Dec 2019 14:11:00 +0300 Subject: [PATCH] Add type and function specs --- lib/uuid.ex | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++-- mix.exs | 9 +++++--- mix.lock | 2 ++ 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/lib/uuid.ex b/lib/uuid.ex index e651e78..18453ab 100644 --- a/lib/uuid.ex +++ b/lib/uuid.ex @@ -5,6 +5,47 @@ defmodule UUID do See [RFC 4122](http://www.ietf.org/rfc/rfc4122.txt). """ + @typedoc "One of representations of UUID." + @type t :: str | raw | hex | urn + + @typedoc "String representation of UUID." + @type str :: <<_ :: 288>> + + @typedoc "Raw binary representation of UUID." + @type raw :: <<_ :: 128>> + + @typedoc "Hex representation of UUID." + @type hex :: <<_ :: 256>> + + @typedoc "URN representation of UUID." + @type urn :: <<_ :: 360>> + + @typedoc "Type of UUID representation." + @type type :: :default | :raw | :hex | :urn + + @typedoc "UUID version." + @type version :: 1 | 3 | 4 | 5 + + @typedoc "Variant of UUID: see RFC for the details." + @type variant :: :reserved_future + | :reserved_microsoft + | :rfc4122 + | :reserved_ncs + + @typedoc """ + Namespace for UUID v3 and v5 (with some predefined UUIDs as atom aliases). + """ + @type namespace :: :dns | :url | :oid | :x500 | :nil | str + + @typedoc "Information about given UUID (see `info/1`)" + @type info :: [ + uuid: str, + binary: raw, + type: type, + version: version, + variant: variant + ] + @nanosec_intervals_offset 122_192_928_000_000_000 # 15 Oct 1582 to 1 Jan 1970. @nanosec_intervals_factor 10 # Microseconds to nanoseconds factor. @@ -69,6 +110,7 @@ defmodule UUID do ``` """ + @spec info(str) :: {:ok, info} | {:error, any} def info(uuid) do try do {:ok, UUID.info!(uuid)} @@ -126,6 +168,7 @@ defmodule UUID do ``` """ + @spec info!(str) :: info def info!(<> = uuid_string) do {type, <>} = uuid_string_to_hex_pair(uuid) <<_::48, version::4, _::12, v0::1, v1::1, v2::1, _::61>> = <> @@ -167,6 +210,8 @@ defmodule UUID do ``` """ + @spec binary_to_string!(raw) :: str + @spec binary_to_string!(raw, type) :: t def binary_to_string!(uuid, format \\ :default) def binary_to_string!(<>, format) do uuid_to_string(<>, format) @@ -203,6 +248,7 @@ defmodule UUID do ``` """ + @spec string_to_binary!(str) :: raw def string_to_binary!(<>) do {_type, <>} = uuid_string_to_hex_pair(uuid) <> @@ -238,6 +284,8 @@ defmodule UUID do ``` """ + @spec uuid1() :: str + @spec uuid1(type) :: t def uuid1(format \\ :default) do uuid1(uuid1_clockseq(), uuid1_node(), format) end @@ -270,6 +318,8 @@ defmodule UUID do ``` """ + @spec uuid1(clock_seq :: <<_::14>>, node :: <<_::48>>) :: str + @spec uuid1(clock_seq :: <<_::14>>, node :: <<_::48>>, type) :: t def uuid1(clock_seq, node, format \\ :default) def uuid1(<>, <>, format) do <> = uuid1_time() @@ -317,6 +367,8 @@ defmodule UUID do ``` """ + @spec uuid3(namespace, name :: binary) :: str + @spec uuid3(namespace, name :: binary, type) :: t def uuid3(namespace_or_uuid, name, format \\ :default) def uuid3(:dns, <>, format) do namebased_uuid(:md5, <<0x6ba7b8109dad11d180b400c04fd430c8::128, name::binary>>) @@ -375,8 +427,10 @@ defmodule UUID do ``` """ + @spec uuid4() :: str def uuid4(), do: uuid4(:default) + @spec uuid4(type | :strong | :weak) :: t def uuid4(:strong), do: uuid4(:default) # For backwards compatibility. def uuid4(:weak), do: uuid4(:default) # For backwards compatibility. def uuid4(format) do @@ -419,6 +473,8 @@ defmodule UUID do ``` """ + @spec uuid5(namespace, binary) :: str + @spec uuid5(namespace, name :: binary, type) :: t def uuid5(namespace_or_uuid, name, format \\ :default) def uuid5(:dns, <>, format) do namebased_uuid(:sha1, <<0x6ba7b8109dad11d180b400c04fd430c8::128, name::binary>>) @@ -618,7 +674,7 @@ defmodule UUID do defp variant(_) do raise ArgumentError, message: "Invalid argument; Not valid variant bits" end - + defp hex_str_to_binary(<< a1, a2, a3, a4, a5, a6, a7, a8, b1, b2, b3, b4, c1, c2, c3, c4, @@ -633,7 +689,7 @@ defmodule UUID do d(e5)::4, d(e6)::4, d(e7)::4, d(e8)::4, d(e9)::4, d(e10)::4, d(e11)::4, d(e12)::4 >> end - + @compile {:inline, d: 1} defp d(?0), do: 0 diff --git a/mix.exs b/mix.exs index 63339e4..0624572 100644 --- a/mix.exs +++ b/mix.exs @@ -24,9 +24,12 @@ defmodule UUID.Mixfile do # List of dependencies. defp deps do - [{:ex_doc, "~> 0.19", only: :dev}, - {:earmark, "~> 1.2", only: :dev}, - {:benchfella, "~> 0.3", only: :dev}] + [ + {:ex_doc, "~> 0.19", only: :dev}, + {:earmark, "~> 1.2", only: :dev}, + {:benchfella, "~> 0.3", only: :dev}, + {:dialyxir, only: :dev}, + ] end # Description. diff --git a/mix.lock b/mix.lock index abf4863..e1202b4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,8 @@ %{ "benchfella": {:hex, :benchfella, "0.3.5", "b2122c234117b3f91ed7b43b6e915e19e1ab216971154acd0a80ce0e9b8c05f5", [:mix], [], "hexpm"}, + "dialyxir": {:hex, :dialyxir, "1.0.0-rc.7", "6287f8f2cb45df8584317a4be1075b8c9b8a69de8eeb82b4d9e6c761cf2664cd", [:mix], [{:erlex, ">= 0.2.5", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.4.2", "3aa0bd23bc4c61cf2f1e5d752d1bb470560a6f8539974f767a38923bb20e1d7f", [:mix], [], "hexpm"}, + "erlex": {:hex, :erlex, "0.2.5", "e51132f2f472e13d606d808f0574508eeea2030d487fc002b46ad97e738b0510", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},