Add RDF.Resource.Generator
This commit is contained in:
parent
b89b5d34d2
commit
db007641e2
9 changed files with 124 additions and 3 deletions
|
@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
|
|||
|
||||
### Added
|
||||
|
||||
- `RDF.Resource.Generator`s which can be used to generate configurable ids
|
||||
- `:implicit_base` option on the `RDF.Turtle.Encoder`
|
||||
- `:base_description` option on the `RDF.Turtle.Encoder`
|
||||
- `RDF.Resource.t` type
|
||||
|
|
|
@ -41,10 +41,11 @@ defmodule RDF do
|
|||
"""
|
||||
|
||||
alias RDF.{
|
||||
Resource,
|
||||
IRI,
|
||||
Namespace,
|
||||
Literal,
|
||||
BlankNode,
|
||||
Literal,
|
||||
Namespace,
|
||||
Description,
|
||||
Graph,
|
||||
Dataset,
|
||||
|
@ -191,6 +192,9 @@ defmodule RDF do
|
|||
|
||||
def resource?(_), do: false
|
||||
|
||||
defdelegate resource(), to: Resource, as: :new
|
||||
defdelegate resource(args), to: Resource, as: :new
|
||||
|
||||
@doc """
|
||||
Checks if the given value is a RDF term.
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ defmodule RDF.BlankNode do
|
|||
@enforce_keys [:value]
|
||||
defstruct [:value]
|
||||
|
||||
use RDF.Resource.Generator
|
||||
|
||||
@doc """
|
||||
Creates a `RDF.BlankNode`.
|
||||
"""
|
||||
|
@ -44,6 +46,9 @@ defmodule RDF.BlankNode do
|
|||
"""
|
||||
def value(%__MODULE__{} = bnode), do: bnode.value
|
||||
|
||||
@impl RDF.Resource.Generator
|
||||
def generate(), do: new()
|
||||
|
||||
@doc """
|
||||
Tests for value equality of blank nodes.
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ defmodule RDF.BlankNode.Generator do
|
|||
"""
|
||||
|
||||
use GenServer
|
||||
use RDF.Resource.Generator
|
||||
|
||||
# Client API ###############################################################
|
||||
|
||||
|
@ -64,10 +65,16 @@ defmodule RDF.BlankNode.Generator do
|
|||
@doc """
|
||||
Generates a new blank node according to the `RDF.BlankNode.Generator.Algorithm` set up.
|
||||
"""
|
||||
@impl RDF.Resource.Generator
|
||||
def generate(pid) do
|
||||
GenServer.call(pid, :generate)
|
||||
end
|
||||
|
||||
@impl RDF.Resource.Generator
|
||||
def generate do
|
||||
raise ArgumentError, "required pid of RDF.BlankNode.Generator missing"
|
||||
end
|
||||
|
||||
@doc """
|
||||
Generates a blank node for a given value according to the `RDF.BlankNode.Generator.Algorithm` set up.
|
||||
"""
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
defmodule RDF.Resource do
|
||||
alias RDF.{IRI, BlankNode}
|
||||
alias RDF.Resource.Generator
|
||||
|
||||
@type t :: IRI.t() | BlankNode.t()
|
||||
|
||||
@default_generator (Application.get_env(:rdf, :resource) || [generator: BlankNode])
|
||||
|> Generator.config()
|
||||
|
||||
def new(), do: Generator.generate(@default_generator, nil)
|
||||
def new(args), do: Generator.generate(@default_generator, args)
|
||||
end
|
||||
|
|
57
lib/rdf/resource_generator.ex
Normal file
57
lib/rdf/resource_generator.ex
Normal file
|
@ -0,0 +1,57 @@
|
|||
defmodule RDF.Resource.Generator do
|
||||
defmodule Config do
|
||||
@enforce_keys [:generator]
|
||||
defstruct [:generator, :arguments]
|
||||
|
||||
@type t :: %__MODULE__{generator: module, arguments: any}
|
||||
end
|
||||
|
||||
@callback generator_config() :: Config.t()
|
||||
@callback generator_config(args :: any) :: Config.t()
|
||||
|
||||
@callback generator_arguments(args :: any, defaults :: any) :: any
|
||||
|
||||
@callback generate() :: RDF.Resource.t()
|
||||
|
||||
@callback generate(args :: any) :: RDF.Resource.t()
|
||||
|
||||
defmacro __using__(_opts) do
|
||||
quote do
|
||||
@behaviour RDF.Resource.Generator
|
||||
|
||||
@impl RDF.Resource.Generator
|
||||
def generator_config(defaults \\ nil) do
|
||||
%RDF.Resource.Generator.Config{
|
||||
generator: __MODULE__,
|
||||
arguments: generator_arguments(defaults, nil)
|
||||
}
|
||||
end
|
||||
|
||||
@impl RDF.Resource.Generator
|
||||
def generator_arguments(args, defaults) when is_list(args) and is_list(defaults),
|
||||
do: Keyword.merge(defaults, args)
|
||||
|
||||
def generator_arguments(nil, defaults), do: defaults
|
||||
def generator_arguments(args, defaults), do: args
|
||||
|
||||
@impl RDF.Resource.Generator
|
||||
def generate(_args), do: generate()
|
||||
|
||||
defoverridable generate: 1, generator_config: 1, generator_arguments: 2
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
def config(config) do
|
||||
{generator, args} = Keyword.pop!(config, :generator)
|
||||
default_args = unless Enum.empty?(args), do: args
|
||||
generator.generator_config(default_args)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def generate(%Config{generator: generator, arguments: defaults}, args),
|
||||
do: do_generate(generator, generator.generator_arguments(args, defaults))
|
||||
|
||||
defp do_generate(generator, nil), do: generator.generate()
|
||||
defp do_generate(generator, args), do: generator.generate(args)
|
||||
end
|
|
@ -12,7 +12,7 @@ defmodule RDF.Test.Case do
|
|||
|
||||
using do
|
||||
quote do
|
||||
alias RDF.{Dataset, Graph, Description, IRI, XSD, PrefixMap, PropertyMap, NS}
|
||||
alias RDF.{Dataset, Graph, Description, IRI, BlankNode, XSD, PrefixMap, PropertyMap, NS}
|
||||
alias RDF.NS.{RDFS, OWL}
|
||||
alias unquote(__MODULE__).{EX, FOAF}
|
||||
|
||||
|
|
29
test/unit/resource_generator_test.exs
Normal file
29
test/unit/resource_generator_test.exs
Normal file
|
@ -0,0 +1,29 @@
|
|||
defmodule RDF.ResourceId.GeneratorTest do
|
||||
use RDF.Test.Case
|
||||
|
||||
doctest RDF.Resource.Generator
|
||||
|
||||
alias RDF.Resource.Generator
|
||||
|
||||
test "RDF.BlankNode as a generator" do
|
||||
assert %BlankNode{} = bnode1 = Generator.generate(BlankNode.generator_config(), nil)
|
||||
assert %BlankNode{} = bnode2 = Generator.generate(BlankNode.generator_config(), nil)
|
||||
assert bnode1 != bnode2
|
||||
end
|
||||
|
||||
test "RDF.BlankNode.Generator as a generator" do
|
||||
{:ok, generator} = start_supervised({RDF.BlankNode.Generator, RDF.BlankNode.Increment})
|
||||
|
||||
assert RDF.BlankNode.Generator.generator_config(generator)
|
||||
|> Generator.generate(nil) ==
|
||||
RDF.bnode(0)
|
||||
|
||||
assert RDF.BlankNode.Generator.generator_config(generator)
|
||||
|> Generator.generate(nil) ==
|
||||
RDF.bnode(1)
|
||||
|
||||
assert RDF.BlankNode.Generator.generator_config(:foo)
|
||||
|> Generator.generate(generator) ==
|
||||
RDF.bnode(2)
|
||||
end
|
||||
end
|
11
test/unit/resource_test.exs
Normal file
11
test/unit/resource_test.exs
Normal file
|
@ -0,0 +1,11 @@
|
|||
defmodule RDF.ResourceTest do
|
||||
use RDF.Test.Case
|
||||
|
||||
doctest RDF.Resource
|
||||
|
||||
alias RDF.Resource
|
||||
|
||||
test "new/0" do
|
||||
assert %BlankNode{} = Resource.new()
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue