rdf-ex/lib/rdf/blank_node/increment.ex
2020-10-28 11:51:00 +01:00

63 lines
1.6 KiB
Elixir

defmodule RDF.BlankNode.Increment do
@moduledoc """
An implementation of a `RDF.BlankNode.Generator.Algorithm` which returns `RDF.BlankNode`s with incremented identifiers.
The following options are supported when starting a `RDF.BlankNode.Generator`
with this algorithm:
- `prefix`: a string prepended to the generated blank node identifier
- `start_value`: the number from which the incremented counter starts
"""
@behaviour RDF.BlankNode.Generator.Algorithm
alias RDF.BlankNode
@type state :: %{
optional(:prefix) => String.t(),
map: map,
counter: pos_integer
}
@impl BlankNode.Generator.Algorithm
def init(%{prefix: prefix} = opts) do
opts
|> Map.delete(:prefix)
|> init()
|> Map.put(:prefix, prefix)
end
@impl BlankNode.Generator.Algorithm
def init(opts) do
%{
map: %{},
counter: Map.get(opts, :start_value, 0)
}
end
@impl BlankNode.Generator.Algorithm
def generate(%{counter: counter} = state) do
{bnode(counter, state), %{state | counter: counter + 1}}
end
@impl BlankNode.Generator.Algorithm
def generate_for(value, %{map: map, counter: counter} = state) do
case Map.get(map, value) do
nil ->
{bnode(counter, state),
%{state | map: Map.put(map, value, counter), counter: counter + 1}}
previous ->
{bnode(previous, state), state}
end
end
defp bnode(counter, %{prefix: prefix}) do
BlankNode.new(prefix <> Integer.to_string(counter))
end
defp bnode(counter, _) do
BlankNode.new(counter)
end
end