Add RDF.IRI.UUID.Generator

This commit is contained in:
Marcel Otto 2022-03-02 01:55:31 +01:00
parent 62e08f98ee
commit 424909b1f9
5 changed files with 206 additions and 0 deletions

View File

@ -0,0 +1,4 @@
Unknown function 'Elixir.UUID':uuid4/1
Unknown function 'Elixir.UUID':uuid1/1
Unknown function 'Elixir.UUID':uuid3/3
Unknown function 'Elixir.UUID':uuid5/3

View File

@ -0,0 +1,65 @@
# Since optional dependencies don't get started, dialyzer can't find these functions.
# We're ignoring these warnings (via .dialyzer_ignore).
# See https://elixirforum.com/t/confusing-behavior-of-optional-deps-in-mix-exs/17719/4
if Code.ensure_loaded?(UUID) do
defmodule RDF.IRI.UUID.Generator do
use RDF.Resource.Generator
alias RDF.IRI
import RDF.Utils.Guards
@impl true
def generate do
UUID.uuid4(:urn) |> IRI.new()
end
@impl true
def generate(args) do
{prefix, args} = Keyword.pop(args, :prefix)
{uuid_version, args} = Keyword.pop(args, :version, 4)
{uuid_format, args} = Keyword.pop(args, :format, :default)
{namespace, name, args} =
if uuid_version in [3, 5] do
unless Keyword.has_key?(args, :namespace) and Keyword.has_key?(args, :name) do
raise ArgumentError,
"missing required :namespace and :name arguments for UUID version #{uuid_version}"
end
{namespace, args} = Keyword.pop!(args, :namespace)
{name, args} = Keyword.pop!(args, :name)
{namespace, name, args}
else
{nil, nil, args}
end
unless Enum.empty?(args) do
raise ArgumentError, "unknown arguments: #{inspect(args)}"
end
case uuid_version do
1 -> UUID.uuid1(uuid_format)
4 -> UUID.uuid4(uuid_format)
3 -> UUID.uuid3(namespace, name, uuid_format)
5 -> UUID.uuid5(namespace, name, uuid_format)
_ -> raise ArgumentError, "unknown UUID version: #{uuid_version}"
end
|> iri(uuid_format, prefix)
end
defp iri(uuid, :urn, nil), do: IRI.new(uuid)
defp iri(_uuid, :urn, _),
do: raise(ArgumentError, "prefix option not support on URN UUIDs")
defp iri(_, _, nil),
do: raise(ArgumentError, "missing required :prefix argument on non-URN UUIDs")
defp iri(uuid, format, prefix) when maybe_module(prefix),
do: iri(uuid, format, prefix.__base_iri__())
defp iri(uuid, _, prefix), do: IRI.new(prefix <> uuid)
end
end

View File

@ -72,6 +72,7 @@ defmodule RDF.Mixfile do
[
{:decimal, "~> 1.5"},
{:protocol_ex, "~> 0.4.4"},
{:elixir_uuid, "~> 1.2", optional: true},
{:credo, "~> 1.6", only: [:dev, :test], runtime: false},
{:dialyxir, "~> 1.1", only: [:dev, :test], runtime: false},
{:ex_doc, "~> 0.26", only: :dev, runtime: false},

View File

@ -7,6 +7,7 @@
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},
"earmark_parser": {:hex, :earmark_parser, "1.4.18", "e1b2be73eb08a49fb032a0208bf647380682374a725dfb5b9e510def8397f6f2", [:mix], [], "hexpm", "114a0e85ec3cf9e04b811009e73c206394ffecfcc313e0b346de0d557774ee97"},
"elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.26.0", "1922164bac0b18b02f84d6f69cab1b93bc3e870e2ad18d5dacb50a9e06b542a3", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2775d66e494a9a48355db7867478ffd997864c61c65a47d31c4949459281c78d"},
"excoveralls": {:hex, :excoveralls, "0.14.4", "295498f1ae47bdc6dce59af9a585c381e1aefc63298d48172efaaa90c3d251db", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e3ab02f2df4c1c7a519728a6f0a747e71d7d6e846020aae338173619217931c1"},

View File

@ -0,0 +1,135 @@
defmodule RDF.IRI.UUID.GeneratorTest do
use RDF.Test.Case
doctest RDF.IRI.UUID.Generator
alias RDF.Resource.Generator
test "without arguments, a URN is generated" do
assert %IRI{value: "urn:uuid:" <> _} =
IRI.UUID.Generator.generator_config()
|> Generator.generate(nil)
end
test "setting the prefix function arguments" do
assert %IRI{value: "http://example.com/ns/" <> _} =
IRI.UUID.Generator.generator_config(prefix: "http://example.com/ns/")
|> Generator.generate(nil)
assert %IRI{} =
iri1 =
IRI.UUID.Generator.generator_config(prefix: EX)
|> Generator.generate(nil)
assert String.starts_with?(iri1.value, EX.__base_iri__())
assert %IRI{} =
iri2 =
IRI.UUID.Generator.generator_config(prefix: EX)
|> Generator.generate(nil)
assert iri1 != iri2
end
test "setting UUID params via defaults" do
for version <- [1, 4], format <- [:default, :hex] do
assert %IRI{value: "http://example.com/ns/" <> uuid} =
IRI.UUID.Generator.generator_config(
prefix: "http://example.com/ns/",
version: version,
format: format
)
|> Generator.generate(nil)
uuid_info = UUID.info!(uuid)
assert Keyword.get(uuid_info, :version) == version
assert Keyword.get(uuid_info, :type) == format
end
for version <- [3, 5],
format <- [:default, :hex],
namespace <- [:dns, :url, UUID.uuid4()] do
assert %IRI{value: "http://example.com/ns/" <> uuid} =
IRI.UUID.Generator.generator_config(
prefix: "http://example.com/ns/",
version: version,
format: format,
namespace: namespace,
name: "test"
)
|> Generator.generate(nil)
uuid_info = UUID.info!(uuid)
assert Keyword.get(uuid_info, :version) == version
assert Keyword.get(uuid_info, :type) == format
end
end
test "setting UUID params on generate/2" do
for version <- [1, 4], format <- [:default, :hex] do
assert %IRI{value: "http://example.com/ns/" <> uuid} =
IRI.UUID.Generator.generator_config()
|> Generator.generate(
prefix: "http://example.com/ns/",
version: version,
format: format
)
uuid_info = UUID.info!(uuid)
assert Keyword.get(uuid_info, :version) == version
assert Keyword.get(uuid_info, :type) == format
end
for version <- [3, 5],
format <- [:default, :hex],
namespace <- [:dns, :url, UUID.uuid4()] do
assert %IRI{value: "http://example.com/ns/" <> uuid} =
IRI.UUID.Generator.generator_config()
|> Generator.generate(
prefix: "http://example.com/ns/",
version: version,
format: format,
namespace: namespace,
name: "test"
)
uuid_info = UUID.info!(uuid)
assert Keyword.get(uuid_info, :version) == version
assert Keyword.get(uuid_info, :type) == format
end
end
test "overwriting default UUID params on generate/2" do
assert %IRI{value: "http://example.com/ns/" <> uuid} =
IRI.UUID.Generator.generator_config(
prefix: "http://example.com/ns/",
version: 4,
format: :default
)
|> Generator.generate(
version: 1,
format: :hex
)
uuid_info = UUID.info!(uuid)
assert Keyword.get(uuid_info, :version) == 1
assert Keyword.get(uuid_info, :type) == :hex
assert %IRI{value: "http://example.com/ns/" <> uuid} =
IRI.UUID.Generator.generator_config(
prefix: "http://example.com/ns/",
version: 3,
format: :hex,
namespace: :url
)
|> Generator.generate(
version: 5,
namespace: :dns,
name: "example.com"
)
uuid_info = UUID.info!(uuid)
assert Keyword.get(uuid_info, :version) == 5
assert Keyword.get(uuid_info, :type) == :hex
end
end