Rename RDF.Statement.convert* functions to RDF.Statement.coerce*

This commit is contained in:
Marcel Otto 2017-08-11 22:22:27 +02:00
parent 75b84254f4
commit 89d75270aa
13 changed files with 123 additions and 122 deletions

View file

@ -20,12 +20,13 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
### Changed ### Changed
- Rename `RDF.Statement.convert*` functions to `RDF.Statement.coerce*`
- Don't support Elixir versions < 1.4 - Don't support Elixir versions < 1.4
### Fixed ### Fixed
- `RDF.uri/1` and URI parsing of N-Triples and N-Quads decoders preserve empty fragments - `RDF.uri/1` and URI parsing of N-Triples and N-Quads decoders preserve empty fragments
- booleans weren't recognized as convertible literals on object positions - booleans weren't recognized as coercible literals on object positions
- N-Triples and N-Quads decoder didn't handle escaping properly - N-Triples and N-Quads decoder didn't handle escaping properly

View file

@ -382,7 +382,7 @@ Note: Although you can create any XSD datatype by using the resp. URI with the `
RDF statements are generally represented in RDF.ex as native Elixir tuples, either as 3-element tuples for triples or a 4-element tuples for quads. RDF statements are generally represented in RDF.ex as native Elixir tuples, either as 3-element tuples for triples or a 4-element tuples for quads.
The `RDF.Triple` and `RDF.Quad` modules both provide a function `new` for such tuples, which convert the elements to proper nodes when possible or raise an error when such a conversion is not possible. In particular these functions also resolve qualified terms from a vocabulary namespace. They can also be called with the delegator functions `RDF.triple` and `RDF.quad`. The `RDF.Triple` and `RDF.Quad` modules both provide a function `new` for such tuples, which coerces the elements to proper nodes when possible or raise an error when such a coercion is not possible. In particular these functions also resolve qualified terms from a vocabulary namespace. They can also be called with the delegator functions `RDF.triple` and `RDF.quad`.
```elixir ```elixir
iex> RDF.triple(EX.S, EX.p, 1) iex> RDF.triple(EX.S, EX.p, 1)
@ -394,7 +394,7 @@ iex> RDF.quad(EX.S, EX.p, 1, EX.Graph)
~I<http://example.com/Graph>} ~I<http://example.com/Graph>}
iex> RDF.triple {EX.S, 1, EX.O} iex> RDF.triple {EX.S, 1, EX.O}
** (RDF.Triple.InvalidPredicateError) '1' is not a valid predicate of a RDF.Triple ** (RDF.Triple.InvalidPredicateError) '1' is not a valid predicate of a RDF.Triple
(rdf) lib/rdf/statement.ex:53: RDF.Statement.convert_predicate/1 (rdf) lib/rdf/statement.ex:53: RDF.Statement.coerce_predicate/1
(rdf) lib/rdf/triple.ex:26: RDF.Triple.new/3 (rdf) lib/rdf/triple.ex:26: RDF.Triple.new/3
``` ```

View file

@ -96,7 +96,7 @@ end
defimpl RDF.Data, for: RDF.Description do defimpl RDF.Data, for: RDF.Description do
def merge(%RDF.Description{subject: subject} = description, {s, _, _} = triple) do def merge(%RDF.Description{subject: subject} = description, {s, _, _} = triple) do
with ^subject <- RDF.Statement.convert_subject(s) do with ^subject <- RDF.Statement.coerce_subject(s) do
RDF.Description.add(description, triple) RDF.Description.add(description, triple)
else else
_ -> _ ->
@ -138,7 +138,7 @@ defimpl RDF.Data, for: RDF.Description do
do: RDF.Description.describes?(description, subject) do: RDF.Description.describes?(description, subject)
def description(%RDF.Description{subject: subject} = description, s) do def description(%RDF.Description{subject: subject} = description, s) do
with ^subject <- RDF.Statement.convert_subject(s) do with ^subject <- RDF.Statement.coerce_subject(s) do
description description
else else
_ -> RDF.Description.new(s) _ -> RDF.Description.new(s)
@ -163,7 +163,7 @@ end
defimpl RDF.Data, for: RDF.Graph do defimpl RDF.Data, for: RDF.Graph do
def merge(%RDF.Graph{name: name} = graph, {_, _, _, graph_context} = quad) do def merge(%RDF.Graph{name: name} = graph, {_, _, _, graph_context} = quad) do
with ^name <- RDF.Statement.convert_graph_name(graph_context) do with ^name <- RDF.Statement.coerce_graph_name(graph_context) do
RDF.Graph.add(graph, quad) RDF.Graph.add(graph, quad)
else else
_ -> _ ->
@ -246,7 +246,7 @@ defimpl RDF.Data, for: RDF.Dataset do
do: RDF.Dataset.who_describes(dataset, subject) != [] do: RDF.Dataset.who_describes(dataset, subject) != []
def description(dataset, subject) do def description(dataset, subject) do
with subject = RDF.Statement.convert_subject(subject) do with subject = RDF.Statement.coerce_subject(subject) do
Enum.reduce RDF.Dataset.graphs(dataset), RDF.Description.new(subject), fn Enum.reduce RDF.Dataset.graphs(dataset), RDF.Description.new(subject), fn
%RDF.Graph{descriptions: %{^subject => graph_description}}, description -> %RDF.Graph{descriptions: %{^subject => graph_description}}, description ->
RDF.Description.add(description, graph_description) RDF.Description.add(description, graph_description)

View file

@ -106,7 +106,7 @@ defmodule RDF.Dataset do
def add(dataset, statements, graph_context \\ false) def add(dataset, statements, graph_context \\ false)
def add(dataset, statements, graph_context) when is_list(statements) do def add(dataset, statements, graph_context) when is_list(statements) do
with graph_context = graph_context && convert_graph_name(graph_context) do with graph_context = graph_context && coerce_graph_name(graph_context) do
Enum.reduce statements, dataset, fn (statement, dataset) -> Enum.reduce statements, dataset, fn (statement, dataset) ->
add(dataset, statement, graph_context) add(dataset, statement, graph_context)
end end
@ -121,7 +121,7 @@ defmodule RDF.Dataset do
def add(%RDF.Dataset{name: name, graphs: graphs}, def add(%RDF.Dataset{name: name, graphs: graphs},
{subject, predicate, objects, graph_context}, false) do {subject, predicate, objects, graph_context}, false) do
with graph_context = convert_graph_name(graph_context) do with graph_context = coerce_graph_name(graph_context) do
updated_graphs = updated_graphs =
Map.update(graphs, graph_context, Map.update(graphs, graph_context,
Graph.new(graph_context, {subject, predicate, objects}), Graph.new(graph_context, {subject, predicate, objects}),
@ -138,7 +138,7 @@ defmodule RDF.Dataset do
def add(%RDF.Dataset{name: name, graphs: graphs}, def add(%RDF.Dataset{name: name, graphs: graphs},
%Description{} = description, graph_context) do %Description{} = description, graph_context) do
with graph_context = convert_graph_name(graph_context) do with graph_context = coerce_graph_name(graph_context) do
updated_graph = updated_graph =
Map.get(graphs, graph_context, Graph.new(graph_context)) Map.get(graphs, graph_context, Graph.new(graph_context))
|> Graph.add(description) |> Graph.add(description)
@ -159,10 +159,10 @@ defmodule RDF.Dataset do
end end
def add(%RDF.Dataset{} = dataset, %Graph{} = graph, graph_context), def add(%RDF.Dataset{} = dataset, %Graph{} = graph, graph_context),
do: add(dataset, %Graph{graph | name: convert_graph_name(graph_context)}, false) do: add(dataset, %Graph{graph | name: coerce_graph_name(graph_context)}, false)
def add(%RDF.Dataset{} = dataset, %RDF.Dataset{} = other_dataset, graph_context) do def add(%RDF.Dataset{} = dataset, %RDF.Dataset{} = other_dataset, graph_context) do
with graph_context = graph_context && convert_graph_name(graph_context) do with graph_context = graph_context && coerce_graph_name(graph_context) do
Enum.reduce graphs(other_dataset), dataset, fn (graph, dataset) -> Enum.reduce graphs(other_dataset), dataset, fn (graph, dataset) ->
add(dataset, graph, graph_context) add(dataset, graph, graph_context)
end end
@ -194,7 +194,7 @@ defmodule RDF.Dataset do
def put(%RDF.Dataset{name: name, graphs: graphs}, def put(%RDF.Dataset{name: name, graphs: graphs},
{subject, predicate, objects, graph_context}, false) do {subject, predicate, objects, graph_context}, false) do
with graph_context = convert_graph_name(graph_context) do with graph_context = coerce_graph_name(graph_context) do
new_graph = new_graph =
case graphs[graph_context] do case graphs[graph_context] do
graph = %Graph{} -> graph = %Graph{} ->
@ -215,7 +215,7 @@ defmodule RDF.Dataset do
fn fn
{s, _, _} -> {s, nil} {s, _, _} -> {s, nil}
{s, _, _, nil} -> {s, nil} {s, _, _, nil} -> {s, nil}
{s, _, _, c} -> {s, convert_graph_name(c)} {s, _, _, c} -> {s, coerce_graph_name(c)}
end, end,
fn fn
{_, p, o, _} -> {p, o} {_, p, o, _} -> {p, o}
@ -224,7 +224,7 @@ defmodule RDF.Dataset do
end end
def put(%RDF.Dataset{} = dataset, statements, graph_context) when is_list(statements) do def put(%RDF.Dataset{} = dataset, statements, graph_context) when is_list(statements) do
with graph_context = convert_graph_name(graph_context) do with graph_context = coerce_graph_name(graph_context) do
do_put dataset, Enum.group_by(statements, do_put dataset, Enum.group_by(statements,
fn fn
{s, _, _, _} -> {s, graph_context} {s, _, _, _} -> {s, graph_context}
@ -242,7 +242,7 @@ defmodule RDF.Dataset do
def put(%RDF.Dataset{name: name, graphs: graphs}, def put(%RDF.Dataset{name: name, graphs: graphs},
%Description{} = description, graph_context) do %Description{} = description, graph_context) do
with graph_context = convert_graph_name(graph_context) do with graph_context = coerce_graph_name(graph_context) do
updated_graph = updated_graph =
Map.get(graphs, graph_context, Graph.new(graph_context)) Map.get(graphs, graph_context, Graph.new(graph_context))
|> Graph.put(description) |> Graph.put(description)
@ -263,10 +263,10 @@ defmodule RDF.Dataset do
end end
def put(%RDF.Dataset{} = dataset, %Graph{} = graph, graph_context), def put(%RDF.Dataset{} = dataset, %Graph{} = graph, graph_context),
do: put(dataset, %Graph{graph | name: convert_graph_name(graph_context)}, false) do: put(dataset, %Graph{graph | name: coerce_graph_name(graph_context)}, false)
def put(%RDF.Dataset{} = dataset, %RDF.Dataset{} = other_dataset, graph_context) do def put(%RDF.Dataset{} = dataset, %RDF.Dataset{} = other_dataset, graph_context) do
with graph_context = graph_context && convert_graph_name(graph_context) do with graph_context = graph_context && coerce_graph_name(graph_context) do
Enum.reduce graphs(other_dataset), dataset, fn (graph, dataset) -> Enum.reduce graphs(other_dataset), dataset, fn (graph, dataset) ->
put(dataset, graph, graph_context) put(dataset, graph, graph_context)
end end
@ -283,7 +283,7 @@ defmodule RDF.Dataset do
defp do_put(%RDF.Dataset{name: name, graphs: graphs}, defp do_put(%RDF.Dataset{name: name, graphs: graphs},
{subject, graph_context}, predications) {subject, graph_context}, predications)
when is_list(predications) do when is_list(predications) do
with graph_context = convert_graph_name(graph_context) do with graph_context = coerce_graph_name(graph_context) do
graph = Map.get(graphs, graph_context, Graph.new(graph_context)) graph = Map.get(graphs, graph_context, Graph.new(graph_context))
new_graphs = graphs new_graphs = graphs
|> Map.put(graph_context, Graph.put(graph, subject, predications)) |> Map.put(graph_context, Graph.put(graph, subject, predications))
@ -307,7 +307,7 @@ defmodule RDF.Dataset do
def delete(dataset, statements, graph_context \\ false) def delete(dataset, statements, graph_context \\ false)
def delete(%RDF.Dataset{} = dataset, statements, graph_context) when is_list(statements) do def delete(%RDF.Dataset{} = dataset, statements, graph_context) when is_list(statements) do
with graph_context = graph_context && convert_graph_name(graph_context) do with graph_context = graph_context && coerce_graph_name(graph_context) do
Enum.reduce statements, dataset, fn (statement, dataset) -> Enum.reduce statements, dataset, fn (statement, dataset) ->
delete(dataset, statement, graph_context) delete(dataset, statement, graph_context)
end end
@ -346,7 +346,7 @@ defmodule RDF.Dataset do
defp do_delete(%RDF.Dataset{name: name, graphs: graphs} = dataset, defp do_delete(%RDF.Dataset{name: name, graphs: graphs} = dataset,
graph_context, statements) do graph_context, statements) do
with graph_context = convert_graph_name(graph_context), with graph_context = coerce_graph_name(graph_context),
graph when not is_nil(graph) <- graphs[graph_context], graph when not is_nil(graph) <- graphs[graph_context],
new_graph = Graph.delete(graph, statements) new_graph = Graph.delete(graph, statements)
do do
@ -376,7 +376,7 @@ defmodule RDF.Dataset do
end end
def delete_graph(%RDF.Dataset{name: name, graphs: graphs}, graph_name) do def delete_graph(%RDF.Dataset{name: name, graphs: graphs}, graph_name) do
with graph_name = convert_graph_name(graph_name) do with graph_name = coerce_graph_name(graph_name) do
%RDF.Dataset{name: name, graphs: Map.delete(graphs, graph_name)} %RDF.Dataset{name: name, graphs: Map.delete(graphs, graph_name)}
end end
end end
@ -404,7 +404,7 @@ defmodule RDF.Dataset do
:error :error
""" """
def fetch(%RDF.Dataset{graphs: graphs}, graph_name) do def fetch(%RDF.Dataset{graphs: graphs}, graph_name) do
Access.fetch(graphs, convert_graph_name(graph_name)) Access.fetch(graphs, coerce_graph_name(graph_name))
end end
@doc """ @doc """
@ -436,7 +436,7 @@ defmodule RDF.Dataset do
The graph with given name. The graph with given name.
""" """
def graph(%RDF.Dataset{graphs: graphs}, graph_name), def graph(%RDF.Dataset{graphs: graphs}, graph_name),
do: Map.get(graphs, convert_graph_name(graph_name)) do: Map.get(graphs, coerce_graph_name(graph_name))
@doc """ @doc """
The default graph of a `RDF.Dataset`. The default graph of a `RDF.Dataset`.
@ -474,7 +474,7 @@ defmodule RDF.Dataset do
{RDF.Graph.new(EX.Graph, {EX.S, EX.P, EX.O}), RDF.Dataset.new({EX.S, EX.P, EX.NEW, EX.Graph})} {RDF.Graph.new(EX.Graph, {EX.S, EX.P, EX.O}), RDF.Dataset.new({EX.S, EX.P, EX.NEW, EX.Graph})}
""" """
def get_and_update(%RDF.Dataset{} = dataset, graph_name, fun) do def get_and_update(%RDF.Dataset{} = dataset, graph_name, fun) do
with graph_context = convert_graph_name(graph_name) do with graph_context = coerce_graph_name(graph_name) do
case fun.(get(dataset, graph_context)) do case fun.(get(dataset, graph_context)) do
{old_graph, new_graph} -> {old_graph, new_graph} ->
{old_graph, put(dataset, new_graph, graph_context)} {old_graph, put(dataset, new_graph, graph_context)}
@ -523,7 +523,7 @@ defmodule RDF.Dataset do
{nil, dataset} {nil, dataset}
""" """
def pop(%RDF.Dataset{name: name, graphs: graphs} = dataset, graph_name) do def pop(%RDF.Dataset{name: name, graphs: graphs} = dataset, graph_name) do
case Access.pop(graphs, convert_graph_name(graph_name)) do case Access.pop(graphs, coerce_graph_name(graph_name)) do
{nil, _} -> {nil, _} ->
{nil, dataset} {nil, dataset}
{graph, new_graphs} -> {graph, new_graphs} ->
@ -670,7 +670,7 @@ defmodule RDF.Dataset do
def include?(dataset, statement, graph_context \\ nil) def include?(dataset, statement, graph_context \\ nil)
def include?(%RDF.Dataset{graphs: graphs}, triple = {_, _, _}, graph_context) do def include?(%RDF.Dataset{graphs: graphs}, triple = {_, _, _}, graph_context) do
with graph_context = convert_graph_name(graph_context) do with graph_context = coerce_graph_name(graph_context) do
if graph = graphs[graph_context] do if graph = graphs[graph_context] do
Graph.include?(graph, triple) Graph.include?(graph, triple)
else else
@ -694,7 +694,7 @@ defmodule RDF.Dataset do
false false
""" """
def describes?(%RDF.Dataset{graphs: graphs}, subject, graph_context \\ nil) do def describes?(%RDF.Dataset{graphs: graphs}, subject, graph_context \\ nil) do
with graph_context = convert_graph_name(graph_context) do with graph_context = coerce_graph_name(graph_context) do
if graph = graphs[graph_context] do if graph = graphs[graph_context] do
Graph.describes?(graph, subject) Graph.describes?(graph, subject)
else else
@ -716,7 +716,7 @@ defmodule RDF.Dataset do
[nil, RDF.uri(EX.Graph1)] [nil, RDF.uri(EX.Graph1)]
""" """
def who_describes(%RDF.Dataset{graphs: graphs}, subject) do def who_describes(%RDF.Dataset{graphs: graphs}, subject) do
with subject = convert_subject(subject) do with subject = coerce_subject(subject) do
graphs graphs
|> Map.values |> Map.values
|> Stream.filter(&Graph.describes?(&1, subject)) |> Stream.filter(&Graph.describes?(&1, subject))

View file

@ -23,7 +23,7 @@ defmodule RDF.Description do
When given a list of statements, the first one must contain a subject. When given a list of statements, the first one must contain a subject.
""" """
@spec new(RDF.Statement.convertible_subject) :: RDF.Description.t @spec new(RDF.Statement.coercible_subject) :: RDF.Description.t
def new(subject) def new(subject)
def new({subject, predicate, object}), def new({subject, predicate, object}),
@ -33,7 +33,7 @@ defmodule RDF.Description do
def new(%RDF.Description{} = description), def new(%RDF.Description{} = description),
do: description do: description
def new(subject), def new(subject),
do: %RDF.Description{subject: convert_subject(subject)} do: %RDF.Description{subject: coerce_subject(subject)}
@doc """ @doc """
Creates a new `RDF.Description` about the given subject with optional initial statements. Creates a new `RDF.Description` about the given subject with optional initial statements.
@ -75,8 +75,8 @@ defmodule RDF.Description do
end end
def add(%RDF.Description{subject: subject, predications: predications}, predicate, object) do def add(%RDF.Description{subject: subject, predications: predications}, predicate, object) do
with triple_predicate = convert_predicate(predicate), with triple_predicate = coerce_predicate(predicate),
triple_object = convert_object(object), triple_object = coerce_object(object),
new_predications = Map.update(predications, new_predications = Map.update(predications,
triple_predicate, %{triple_object => nil}, fn objects -> triple_predicate, %{triple_object => nil}, fn objects ->
Map.put_new(objects, triple_object, nil) Map.put_new(objects, triple_object, nil)
@ -100,7 +100,7 @@ defmodule RDF.Description do
do: add(description, predicate, object) do: add(description, predicate, object)
def add(description = %RDF.Description{}, {subject, predicate, object}) do def add(description = %RDF.Description{}, {subject, predicate, object}) do
if convert_subject(subject) == description.subject, if coerce_subject(subject) == description.subject,
do: add(description, predicate, object), do: add(description, predicate, object),
else: description else: description
end end
@ -142,9 +142,9 @@ defmodule RDF.Description do
def put(%RDF.Description{subject: subject, predications: predications}, def put(%RDF.Description{subject: subject, predications: predications},
predicate, objects) when is_list(objects) do predicate, objects) when is_list(objects) do
with triple_predicate = convert_predicate(predicate), with triple_predicate = coerce_predicate(predicate),
triple_objects = Enum.reduce(objects, %{}, fn (object, acc) -> triple_objects = Enum.reduce(objects, %{}, fn (object, acc) ->
Map.put_new(acc, convert_object(object), nil) end), Map.put_new(acc, coerce_object(object), nil) end),
do: %RDF.Description{subject: subject, do: %RDF.Description{subject: subject,
predications: Map.put(predications, triple_predicate, triple_objects)} predications: Map.put(predications, triple_predicate, triple_objects)}
end end
@ -175,7 +175,7 @@ defmodule RDF.Description do
do: put(description, predicate, object) do: put(description, predicate, object)
def put(%RDF.Description{} = description, {subject, predicate, object}) do def put(%RDF.Description{} = description, {subject, predicate, object}) do
if convert_subject(subject) == description.subject, if coerce_subject(subject) == description.subject,
do: put(description, predicate, object), do: put(description, predicate, object),
else: description else: description
end end
@ -186,11 +186,11 @@ defmodule RDF.Description do
def put(%RDF.Description{subject: subject} = description, statements) when is_list(statements) do def put(%RDF.Description{subject: subject} = description, statements) when is_list(statements) do
statements statements
|> Stream.map(fn |> Stream.map(fn
{p, o} -> {convert_predicate(p), o} {p, o} -> {coerce_predicate(p), o}
{^subject, p, o} -> {convert_predicate(p), o} {^subject, p, o} -> {coerce_predicate(p), o}
{s, p, o} -> {s, p, o} ->
if convert_subject(s) == subject, if coerce_subject(s) == subject,
do: {convert_predicate(p), o} do: {coerce_predicate(p), o}
bad -> raise ArgumentError, "#{inspect bad} is not a valid statement" bad -> raise ArgumentError, "#{inspect bad} is not a valid statement"
end) end)
|> Stream.filter(&(&1)) # filter nil values |> Stream.filter(&(&1)) # filter nil values
@ -226,8 +226,8 @@ defmodule RDF.Description do
end end
def delete(%RDF.Description{subject: subject, predications: predications} = descr, predicate, object) do def delete(%RDF.Description{subject: subject, predications: predications} = descr, predicate, object) do
with triple_predicate = convert_predicate(predicate), with triple_predicate = coerce_predicate(predicate),
triple_object = convert_object(object) do triple_object = coerce_object(object) do
if (objects = predications[triple_predicate]) && Map.has_key?(objects, triple_object) do if (objects = predications[triple_predicate]) && Map.has_key?(objects, triple_object) do
%RDF.Description{ %RDF.Description{
subject: subject, subject: subject,
@ -260,7 +260,7 @@ defmodule RDF.Description do
do: delete(desc, predicate, object) do: delete(desc, predicate, object)
def delete(description = %RDF.Description{}, {subject, predicate, object}) do def delete(description = %RDF.Description{}, {subject, predicate, object}) do
if convert_subject(subject) == description.subject, if coerce_subject(subject) == description.subject,
do: delete(description, predicate, object), do: delete(description, predicate, object),
else: description else: description
end end
@ -299,7 +299,7 @@ defmodule RDF.Description do
end end
def delete_predicates(%RDF.Description{subject: subject, predications: predications}, property) do def delete_predicates(%RDF.Description{subject: subject, predications: predications}, property) do
with property = convert_predicate(property) do with property = coerce_predicate(property) do
%RDF.Description{subject: subject, predications: Map.delete(predications, property)} %RDF.Description{subject: subject, predications: Map.delete(predications, property)}
end end
end end
@ -321,7 +321,7 @@ defmodule RDF.Description do
:error :error
""" """
def fetch(%RDF.Description{predications: predications}, predicate) do def fetch(%RDF.Description{predications: predications}, predicate) do
with {:ok, objects} <- Access.fetch(predications, convert_predicate(predicate)) do with {:ok, objects} <- Access.fetch(predications, coerce_predicate(predicate)) do
{:ok, Map.keys(objects)} {:ok, Map.keys(objects)}
end end
end end
@ -391,7 +391,7 @@ defmodule RDF.Description do
{[RDF.uri(EX.O1)], RDF.Description.new({EX.S, EX.P2, EX.O2})} {[RDF.uri(EX.O1)], RDF.Description.new({EX.S, EX.P2, EX.O2})}
""" """
def get_and_update(description = %RDF.Description{}, predicate, fun) do def get_and_update(description = %RDF.Description{}, predicate, fun) do
with triple_predicate = convert_predicate(predicate) do with triple_predicate = coerce_predicate(predicate) do
case fun.(get(description, triple_predicate)) do case fun.(get(description, triple_predicate)) do
{objects_to_return, new_objects} -> {objects_to_return, new_objects} ->
{objects_to_return, put(description, triple_predicate, new_objects)} {objects_to_return, put(description, triple_predicate, new_objects)}
@ -435,7 +435,7 @@ defmodule RDF.Description do
{nil, RDF.Description.new({EX.S, EX.P, EX.O})} {nil, RDF.Description.new({EX.S, EX.P, EX.O})}
""" """
def pop(description = %RDF.Description{subject: subject, predications: predications}, predicate) do def pop(description = %RDF.Description{subject: subject, predications: predications}, predicate) do
case Access.pop(predications, convert_predicate(predicate)) do case Access.pop(predications, coerce_predicate(predicate)) do
{nil, _} -> {nil, _} ->
{nil, description} {nil, description}
{objects, new_predications} -> {objects, new_predications} ->
@ -535,8 +535,8 @@ defmodule RDF.Description do
def include?(%RDF.Description{predications: predications}, def include?(%RDF.Description{predications: predications},
{predicate, object}) do {predicate, object}) do
with triple_predicate = convert_predicate(predicate), with triple_predicate = coerce_predicate(predicate),
triple_object = convert_object(object) do triple_object = coerce_object(object) do
predications predications
|> Map.get(triple_predicate, %{}) |> Map.get(triple_predicate, %{})
|> Map.has_key?(triple_object) |> Map.has_key?(triple_object)
@ -545,7 +545,7 @@ defmodule RDF.Description do
def include?(desc = %RDF.Description{subject: desc_subject}, def include?(desc = %RDF.Description{subject: desc_subject},
{subject, predicate, object}) do {subject, predicate, object}) do
convert_subject(subject) == desc_subject && coerce_subject(subject) == desc_subject &&
include?(desc, {predicate, object}) include?(desc, {predicate, object})
end end
@ -563,7 +563,7 @@ defmodule RDF.Description do
false false
""" """
def describes?(%RDF.Description{subject: subject}, other_subject) do def describes?(%RDF.Description{subject: subject}, other_subject) do
with other_subject = convert_subject(other_subject) do with other_subject = coerce_subject(other_subject) do
subject == other_subject subject == other_subject
end end
end end

View file

@ -60,7 +60,7 @@ defmodule RDF.Graph do
Creates an empty named `RDF.Graph`. Creates an empty named `RDF.Graph`.
""" """
def new(name), def new(name),
do: %RDF.Graph{name: convert_graph_name(name)} do: %RDF.Graph{name: coerce_graph_name(name)}
@doc """ @doc """
Creates a named `RDF.Graph` with an initial triple. Creates a named `RDF.Graph` with an initial triple.
@ -117,7 +117,7 @@ defmodule RDF.Graph do
def add(graph, triples) def add(graph, triples)
def add(%RDF.Graph{} = graph, {subject, _, _} = statement), def add(%RDF.Graph{} = graph, {subject, _, _} = statement),
do: do_add(graph, convert_subject(subject), statement) do: do_add(graph, coerce_subject(subject), statement)
def add(graph, {subject, predicate, object, _}), def add(graph, {subject, predicate, object, _}),
do: add(graph, {subject, predicate, object}) do: add(graph, {subject, predicate, object})
@ -161,7 +161,7 @@ defmodule RDF.Graph do
def put(graph, statements) def put(graph, statements)
def put(%RDF.Graph{} = graph, {subject, _, _} = statement), def put(%RDF.Graph{} = graph, {subject, _, _} = statement),
do: do_put(graph, convert_subject(subject), statement) do: do_put(graph, coerce_subject(subject), statement)
def put(graph, {subject, predicate, object, _}), def put(graph, {subject, predicate, object, _}),
do: put(graph, {subject, predicate, object}) do: put(graph, {subject, predicate, object})
@ -192,7 +192,7 @@ defmodule RDF.Graph do
def put(%RDF.Graph{name: name, descriptions: descriptions}, subject, predications) def put(%RDF.Graph{name: name, descriptions: descriptions}, subject, predications)
when is_list(predications) do when is_list(predications) do
with subject = convert_subject(subject) do with subject = coerce_subject(subject) do
# TODO: Can we reduce this case also to do_put somehow? Only the initializer of Map.update differs ... # TODO: Can we reduce this case also to do_put somehow? Only the initializer of Map.update differs ...
%RDF.Graph{name: name, %RDF.Graph{name: name,
descriptions: descriptions:
@ -249,7 +249,7 @@ defmodule RDF.Graph do
def delete(graph, triples) def delete(graph, triples)
def delete(%RDF.Graph{} = graph, {subject, _, _} = triple), def delete(%RDF.Graph{} = graph, {subject, _, _} = triple),
do: do_delete(graph, convert_subject(subject), triple) do: do_delete(graph, coerce_subject(subject), triple)
def delete(graph, {subject, predicate, object, _}), def delete(graph, {subject, predicate, object, _}),
do: delete(graph, {subject, predicate, object}) do: delete(graph, {subject, predicate, object})
@ -300,7 +300,7 @@ defmodule RDF.Graph do
end end
def delete_subjects(%RDF.Graph{name: name, descriptions: descriptions}, subject) do def delete_subjects(%RDF.Graph{name: name, descriptions: descriptions}, subject) do
with subject = convert_subject(subject) do with subject = coerce_subject(subject) do
%RDF.Graph{name: name, descriptions: Map.delete(descriptions, subject)} %RDF.Graph{name: name, descriptions: Map.delete(descriptions, subject)}
end end
end end
@ -320,7 +320,7 @@ defmodule RDF.Graph do
:error :error
""" """
def fetch(%RDF.Graph{descriptions: descriptions}, subject) do def fetch(%RDF.Graph{descriptions: descriptions}, subject) do
Access.fetch(descriptions, convert_subject(subject)) Access.fetch(descriptions, coerce_subject(subject))
end end
@doc """ @doc """
@ -349,7 +349,7 @@ defmodule RDF.Graph do
The `RDF.Description` of the given subject. The `RDF.Description` of the given subject.
""" """
def description(%RDF.Graph{descriptions: descriptions}, subject), def description(%RDF.Graph{descriptions: descriptions}, subject),
do: Map.get(descriptions, convert_subject(subject)) do: Map.get(descriptions, coerce_subject(subject))
@doc """ @doc """
All `RDF.Description`s within a `RDF.Graph`. All `RDF.Description`s within a `RDF.Graph`.
@ -381,7 +381,7 @@ defmodule RDF.Graph do
{RDF.Description.new(EX.S, EX.P, EX.O), RDF.Graph.new(EX.S, EX.P, EX.NEW)} {RDF.Description.new(EX.S, EX.P, EX.O), RDF.Graph.new(EX.S, EX.P, EX.NEW)}
""" """
def get_and_update(%RDF.Graph{} = graph, subject, fun) do def get_and_update(%RDF.Graph{} = graph, subject, fun) do
with subject = convert_subject(subject) do with subject = coerce_subject(subject) do
case fun.(get(graph, subject)) do case fun.(get(graph, subject)) do
{old_description, new_description} -> {old_description, new_description} ->
{old_description, put(graph, subject, new_description)} {old_description, put(graph, subject, new_description)}
@ -427,7 +427,7 @@ defmodule RDF.Graph do
{nil, RDF.Graph.new({EX.S, EX.P, EX.O})} {nil, RDF.Graph.new({EX.S, EX.P, EX.O})}
""" """
def pop(%RDF.Graph{name: name, descriptions: descriptions} = graph, subject) do def pop(%RDF.Graph{name: name, descriptions: descriptions} = graph, subject) do
case Access.pop(descriptions, convert_subject(subject)) do case Access.pop(descriptions, coerce_subject(subject)) do
{nil, _} -> {nil, _} ->
{nil, graph} {nil, graph}
{description, new_descriptions} -> {description, new_descriptions} ->
@ -574,7 +574,7 @@ defmodule RDF.Graph do
""" """
def include?(%RDF.Graph{descriptions: descriptions}, def include?(%RDF.Graph{descriptions: descriptions},
triple = {subject, _, _}) do triple = {subject, _, _}) do
with subject = convert_subject(subject), with subject = coerce_subject(subject),
%Description{} <- description = descriptions[subject] do %Description{} <- description = descriptions[subject] do
Description.include?(description, triple) Description.include?(description, triple)
else else
@ -593,7 +593,7 @@ defmodule RDF.Graph do
false false
""" """
def describes?(%RDF.Graph{descriptions: descriptions}, subject) do def describes?(%RDF.Graph{descriptions: descriptions}, subject) do
with subject = convert_subject(subject) do with subject = coerce_subject(subject) do
Map.has_key?(descriptions, subject) Map.has_key?(descriptions, subject)
end end
end end

View file

@ -51,7 +51,7 @@ defmodule RDF.List do
@doc """ @doc """
Creates a `RDF.List` from a native Elixir list or any other `Enumerable` with convertible RDF values. Creates a `RDF.List` from a native Elixir list or any other `Enumerable` with coercible RDF values.
By default the statements constituting the `Enumerable` are added to an empty graph. An By default the statements constituting the `Enumerable` are added to an empty graph. An
already existing graph to which the statements are added can be specified with already existing graph to which the statements are added can be specified with

View file

@ -11,7 +11,7 @@ defmodule RDF.Quad do
@doc """ @doc """
Creates a `RDF.Quad` with proper RDF values. Creates a `RDF.Quad` with proper RDF values.
An error is raised when the given elements are not convertible to RDF values. An error is raised when the given elements are not coercible to RDF values.
Note: The `RDF.quad` function is a shortcut to this function. Note: The `RDF.quad` function is a shortcut to this function.
@ -24,17 +24,17 @@ defmodule RDF.Quad do
""" """
def new(subject, predicate, object, graph_context) do def new(subject, predicate, object, graph_context) do
{ {
Statement.convert_subject(subject), Statement.coerce_subject(subject),
Statement.convert_predicate(predicate), Statement.coerce_predicate(predicate),
Statement.convert_object(object), Statement.coerce_object(object),
Statement.convert_graph_name(graph_context) Statement.coerce_graph_name(graph_context)
} }
end end
@doc """ @doc """
Creates a `RDF.Quad` with proper RDF values. Creates a `RDF.Quad` with proper RDF values.
An error is raised when the given elements are not convertible to RDF values. An error is raised when the given elements are not coercible to RDF values.
Note: The `RDF.quad` function is a shortcut to this function. Note: The `RDF.quad` function is a shortcut to this function.

View file

@ -12,16 +12,16 @@ defmodule RDF.Statement do
@type object :: URI.t | BlankNode.t | Literal.t @type object :: URI.t | BlankNode.t | Literal.t
@type graph_name :: URI.t | BlankNode.t @type graph_name :: URI.t | BlankNode.t
@type convertible_subject :: subject | atom | String.t @type coercible_subject :: subject | atom | String.t
@type convertible_predicate :: predicate | atom | String.t @type coercible_predicate :: predicate | atom | String.t
@type convertible_object :: object | atom | String.t # TODO: all basic Elixir types convertible to Literals @type coercible_object :: object | atom | String.t # TODO: all basic Elixir types coercible to Literals
@type convertible_graph_name :: graph_name | atom | String.t @type coercible_graph_name :: graph_name | atom | String.t
@doc """ @doc """
Creates a `RDF.Statement` tuple with proper RDF values. Creates a `RDF.Statement` tuple with proper RDF values.
An error is raised when the given elements are not convertible to RDF values. An error is raised when the given elements are not coercible to RDF values.
## Examples ## Examples
@ -30,46 +30,46 @@ defmodule RDF.Statement do
iex> RDF.Statement.new {"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"} iex> RDF.Statement.new {"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"}
{~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>} {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>}
""" """
def convert(statement) def coerce(statement)
def convert({_, _, _} = triple), do: Triple.new(triple) def coerce({_, _, _} = triple), do: Triple.new(triple)
def convert({_, _, _, _} = quad), do: Quad.new(quad) def coerce({_, _, _, _} = quad), do: Quad.new(quad)
@doc false @doc false
def convert_subject(uri) def coerce_subject(uri)
def convert_subject(uri = %URI{}), do: uri def coerce_subject(uri = %URI{}), do: uri
def convert_subject(bnode = %BlankNode{}), do: bnode def coerce_subject(bnode = %BlankNode{}), do: bnode
def convert_subject("_:" <> identifier), do: RDF.bnode(identifier) def coerce_subject("_:" <> identifier), do: RDF.bnode(identifier)
def convert_subject(uri) when is_atom(uri) or is_binary(uri), do: RDF.uri(uri) def coerce_subject(uri) when is_atom(uri) or is_binary(uri), do: RDF.uri(uri)
def convert_subject(arg), do: raise RDF.Triple.InvalidSubjectError, subject: arg def coerce_subject(arg), do: raise RDF.Triple.InvalidSubjectError, subject: arg
@doc false @doc false
def convert_predicate(uri) def coerce_predicate(uri)
def convert_predicate(uri = %URI{}), do: uri def coerce_predicate(uri = %URI{}), do: uri
# Note: Although, RDF does not allow blank nodes for properties, JSON-LD allows # Note: Although, RDF does not allow blank nodes for properties, JSON-LD allows
# them, by introducing the notion of "generalized RDF". # them, by introducing the notion of "generalized RDF".
# TODO: Support an option `:strict_rdf` to explicitly disallow them or produce warnings or ... # TODO: Support an option `:strict_rdf` to explicitly disallow them or produce warnings or ...
def convert_predicate(bnode = %BlankNode{}), do: bnode def coerce_predicate(bnode = %BlankNode{}), do: bnode
def convert_predicate(uri) when is_atom(uri) or is_binary(uri), do: RDF.uri(uri) def coerce_predicate(uri) when is_atom(uri) or is_binary(uri), do: RDF.uri(uri)
def convert_predicate(arg), do: raise RDF.Triple.InvalidPredicateError, predicate: arg def coerce_predicate(arg), do: raise RDF.Triple.InvalidPredicateError, predicate: arg
@doc false @doc false
def convert_object(uri) def coerce_object(uri)
def convert_object(uri = %URI{}), do: uri def coerce_object(uri = %URI{}), do: uri
def convert_object(literal = %Literal{}), do: literal def coerce_object(literal = %Literal{}), do: literal
def convert_object(bnode = %BlankNode{}), do: bnode def coerce_object(bnode = %BlankNode{}), do: bnode
def convert_object(bool) when is_boolean(bool), do: Literal.new(bool) def coerce_object(bool) when is_boolean(bool), do: Literal.new(bool)
def convert_object(atom) when is_atom(atom), do: RDF.uri(atom) def coerce_object(atom) when is_atom(atom), do: RDF.uri(atom)
def convert_object(arg), do: Literal.new(arg) def coerce_object(arg), do: Literal.new(arg)
@doc false @doc false
def convert_graph_name(uri) def coerce_graph_name(uri)
def convert_graph_name(nil), do: nil def coerce_graph_name(nil), do: nil
def convert_graph_name(uri = %URI{}), do: uri def coerce_graph_name(uri = %URI{}), do: uri
def convert_graph_name(bnode = %BlankNode{}), do: bnode def coerce_graph_name(bnode = %BlankNode{}), do: bnode
def convert_graph_name("_:" <> identifier), do: RDF.bnode(identifier) def coerce_graph_name("_:" <> identifier), do: RDF.bnode(identifier)
def convert_graph_name(uri) when is_atom(uri) or is_binary(uri), def coerce_graph_name(uri) when is_atom(uri) or is_binary(uri),
do: RDF.uri(uri) do: RDF.uri(uri)
def convert_graph_name(arg), def coerce_graph_name(arg),
do: raise RDF.Quad.InvalidGraphContextError, graph_context: arg do: raise RDF.Quad.InvalidGraphContextError, graph_context: arg
end end

View file

@ -11,7 +11,7 @@ defmodule RDF.Triple do
@doc """ @doc """
Creates a `RDF.Triple` with proper RDF values. Creates a `RDF.Triple` with proper RDF values.
An error is raised when the given elements are not convertible to RDF values. An error is raised when the given elements are not coercible to RDF values.
Note: The `RDF.triple` function is a shortcut to this function. Note: The `RDF.triple` function is a shortcut to this function.
@ -24,16 +24,16 @@ defmodule RDF.Triple do
""" """
def new(subject, predicate, object) do def new(subject, predicate, object) do
{ {
Statement.convert_subject(subject), Statement.coerce_subject(subject),
Statement.convert_predicate(predicate), Statement.coerce_predicate(predicate),
Statement.convert_object(object) Statement.coerce_object(object)
} }
end end
@doc """ @doc """
Creates a `RDF.Triple` with proper RDF values. Creates a `RDF.Triple` with proper RDF values.
An error is raised when the given elements are not convertible to RDF values. An error is raised when the given elements are not coercible to RDF values.
Note: The `RDF.triple` function is a shortcut to this function. Note: The `RDF.triple` function is a shortcut to this function.

View file

@ -14,7 +14,7 @@ defmodule RDF.DatasetTest do
assert named_dataset?(named_dataset()) assert named_dataset?(named_dataset())
end end
test "creating an empty dataset with a convertible dataset name" do test "creating an empty dataset with a coercible dataset name" do
assert named_dataset("http://example.com/DatasetName") assert named_dataset("http://example.com/DatasetName")
|> named_dataset?(uri("http://example.com/DatasetName")) |> named_dataset?(uri("http://example.com/DatasetName"))
assert named_dataset(EX.Foo) |> named_dataset?(uri(EX.Foo)) assert named_dataset(EX.Foo) |> named_dataset?(uri(EX.Foo))
@ -124,13 +124,13 @@ defmodule RDF.DatasetTest do
assert dataset_includes_statement?(ds, {EX.Subject, EX.predicate, EX.Object}) assert dataset_includes_statement?(ds, {EX.Subject, EX.predicate, EX.Object})
end end
test "a convertible triple" do test "a coercible triple" do
assert Dataset.add(dataset(), assert Dataset.add(dataset(),
{"http://example.com/Subject", EX.predicate, EX.Object}) {"http://example.com/Subject", EX.predicate, EX.Object})
|> dataset_includes_statement?({EX.Subject, EX.predicate, EX.Object}) |> dataset_includes_statement?({EX.Subject, EX.predicate, EX.Object})
end end
test "a convertible quad" do test "a coercible quad" do
assert Dataset.add(dataset(), assert Dataset.add(dataset(),
{"http://example.com/Subject", EX.predicate, EX.Object, "http://example.com/GraphName"}) {"http://example.com/Subject", EX.predicate, EX.Object, "http://example.com/GraphName"})
|> dataset_includes_statement?({EX.Subject, EX.predicate, EX.Object, EX.GraphName}) |> dataset_includes_statement?({EX.Subject, EX.predicate, EX.Object, EX.GraphName})
@ -427,7 +427,7 @@ defmodule RDF.DatasetTest do
assert Dataset.add(ds, {EX.Subject, EX.predicate, EX.Object, EX.GraphName}) == ds assert Dataset.add(ds, {EX.Subject, EX.predicate, EX.Object, EX.GraphName}) == ds
end end
test "non-convertible statements elements are causing an error" do test "non-coercible statements elements are causing an error" do
assert_raise RDF.InvalidURIError, fn -> assert_raise RDF.InvalidURIError, fn ->
Dataset.add(dataset(), {"not a URI", EX.predicate, uri(EX.Object), uri(EX.GraphName)}) Dataset.add(dataset(), {"not a URI", EX.predicate, uri(EX.Object), uri(EX.GraphName)})
end end

View file

@ -54,7 +54,7 @@ defmodule RDF.DescriptionTest do
assert description_includes_predication(desc2, {EX.predicate, uri(EX.Object)}) assert description_includes_predication(desc2, {EX.predicate, uri(EX.Object)})
end end
test "from a map with convertible RDF term" do test "from a map with coercible RDF term" do
desc = Description.new(EX.Subject, %{EX.Predicate => EX.Object}) desc = Description.new(EX.Subject, %{EX.Predicate => EX.Object})
assert description_of_subject(desc, uri(EX.Subject)) assert description_of_subject(desc, uri(EX.Subject))
assert description_includes_predication(desc, {uri(EX.Predicate), uri(EX.Object)}) assert description_includes_predication(desc, {uri(EX.Predicate), uri(EX.Object)})
@ -79,7 +79,7 @@ defmodule RDF.DescriptionTest do
|> description_includes_predication({EX.predicate, uri(EX.Object)}) |> description_includes_predication({EX.predicate, uri(EX.Object)})
end end
test "a predicate-object-pair of convertible RDF terms" do test "a predicate-object-pair of coercible RDF terms" do
assert Description.add(description(), assert Description.add(description(),
"http://example.com/predicate", uri(EX.Object)) "http://example.com/predicate", uri(EX.Object))
|> description_includes_predication({EX.predicate, uri(EX.Object)}) |> description_includes_predication({EX.predicate, uri(EX.Object)})
@ -161,7 +161,7 @@ defmodule RDF.DescriptionTest do
assert description_includes_predication(desc, {EX.predicate1, uri(EX.Object4)}) assert description_includes_predication(desc, {EX.predicate1, uri(EX.Object4)})
end end
test "a map of predications with convertible RDF terms" do test "a map of predications with coercible RDF terms" do
desc = description([{EX.predicate1, EX.Object1}, {EX.predicate2, EX.Object2}]) desc = description([{EX.predicate1, EX.Object1}, {EX.predicate2, EX.Object2}])
|> Description.add(%{EX.predicate3 => EX.Object3}) |> Description.add(%{EX.predicate3 => EX.Object3})
@ -181,7 +181,7 @@ defmodule RDF.DescriptionTest do
assert description_includes_predication(desc, {EX.predicate3, bnode(:foo)}) assert description_includes_predication(desc, {EX.predicate3, bnode(:foo)})
end end
test "a map of predications with inconvertible RDF terms" do test "a map of predications with non-coercible RDF terms" do
assert_raise RDF.InvalidURIError, fn -> assert_raise RDF.InvalidURIError, fn ->
Description.add(description(), %{"not a URI" => uri(EX.Object)}) Description.add(description(), %{"not a URI" => uri(EX.Object)})
end end
@ -200,7 +200,7 @@ defmodule RDF.DescriptionTest do
assert Description.add(desc, {EX.predicate, literal(42)}) == desc assert Description.add(desc, {EX.predicate, literal(42)}) == desc
end end
test "non-convertible Triple elements are causing an error" do test "non-coercible Triple elements are causing an error" do
assert_raise RDF.InvalidURIError, fn -> assert_raise RDF.InvalidURIError, fn ->
Description.add(description(), {"not a URI", uri(EX.Object)}) Description.add(description(), {"not a URI", uri(EX.Object)})
end end

View file

@ -19,7 +19,7 @@ defmodule RDF.GraphTest do
|> named_graph?(bnode("graph_name")) |> named_graph?(bnode("graph_name"))
end end
test "creating an empty graph with a convertible graph name" do test "creating an empty graph with a coercible graph name" do
assert named_graph("http://example.com/graph/GraphName") assert named_graph("http://example.com/graph/GraphName")
|> named_graph?(uri("http://example.com/graph/GraphName")) |> named_graph?(uri("http://example.com/graph/GraphName"))
assert named_graph(EX.Foo) |> named_graph?(uri(EX.Foo)) assert named_graph(EX.Foo) |> named_graph?(uri(EX.Foo))
@ -112,7 +112,7 @@ defmodule RDF.GraphTest do
|> graph_includes_statement?({EX.Subject, EX.predicate, EX.Object}) |> graph_includes_statement?({EX.Subject, EX.predicate, EX.Object})
end end
test "a convertible triple" do test "a coercible triple" do
assert Graph.add(graph(), assert Graph.add(graph(),
"http://example.com/Subject", EX.predicate, EX.Object) "http://example.com/Subject", EX.predicate, EX.Object)
|> graph_includes_statement?({EX.Subject, EX.predicate, EX.Object}) |> graph_includes_statement?({EX.Subject, EX.predicate, EX.Object})
@ -189,7 +189,7 @@ defmodule RDF.GraphTest do
assert graph_includes_statement?(g, {EX.Subject3, EX.predicate3, EX.Object3}) assert graph_includes_statement?(g, {EX.Subject3, EX.predicate3, EX.Object3})
end end
test "non-convertible Triple elements are causing an error" do test "non-coercible Triple elements are causing an error" do
assert_raise RDF.InvalidURIError, fn -> assert_raise RDF.InvalidURIError, fn ->
Graph.add(graph(), {"not a URI", EX.predicate, uri(EX.Object)}) Graph.add(graph(), {"not a URI", EX.predicate, uri(EX.Object)})
end end