Use also the :context opt and implicit PropertyMap formats in values/2
This commit is contained in:
parent
cafba9f61f
commit
352b8ef1a8
13 changed files with 115 additions and 106 deletions
|
@ -93,10 +93,10 @@ defprotocol RDF.Data do
|
|||
@doc """
|
||||
Returns a nested map of the native Elixir values of a RDF data structure.
|
||||
|
||||
When the optional `property_map` argument is given, predicates will be mapped
|
||||
to the terms defined in the `RDF.PropertyMap` if present.
|
||||
When a `:context` option is given with a `RDF.PropertyMap`, predicates will
|
||||
be mapped to the terms defined in the `RDF.PropertyMap`, if present.
|
||||
"""
|
||||
def values(data, property_map \\ nil)
|
||||
def values(data, opts \\ [])
|
||||
|
||||
@doc """
|
||||
Returns a map representation of a RDF data structure where each element from its statements is mapped with the given function.
|
||||
|
@ -201,8 +201,8 @@ defimpl RDF.Data, for: RDF.Description do
|
|||
def subject_count(_), do: 1
|
||||
def statement_count(description), do: Description.count(description)
|
||||
|
||||
def values(description, property_map \\ nil),
|
||||
do: Description.values(description, property_map)
|
||||
def values(description, opts \\ []),
|
||||
do: Description.values(description, opts)
|
||||
|
||||
def map(description, fun), do: Description.map(description, fun)
|
||||
|
||||
|
@ -292,7 +292,7 @@ defimpl RDF.Data, for: RDF.Graph do
|
|||
|
||||
def subject_count(graph), do: Graph.subject_count(graph)
|
||||
def statement_count(graph), do: Graph.triple_count(graph)
|
||||
def values(graph, property_map \\ nil), do: Graph.values(graph, property_map)
|
||||
def values(graph, opts \\ []), do: Graph.values(graph, opts)
|
||||
def map(graph, fun), do: Graph.map(graph, fun)
|
||||
|
||||
def equal?(graph, %Description{} = description),
|
||||
|
@ -373,7 +373,7 @@ defimpl RDF.Data, for: RDF.Dataset do
|
|||
|
||||
def subject_count(dataset), do: dataset |> subjects |> Enum.count()
|
||||
def statement_count(dataset), do: Dataset.statement_count(dataset)
|
||||
def values(dataset, property_map \\ nil), do: Dataset.values(dataset, property_map)
|
||||
def values(dataset, opts \\ []), do: Dataset.values(dataset, opts)
|
||||
def map(dataset, fun), do: Dataset.map(dataset, fun)
|
||||
|
||||
def equal?(dataset, %Description{} = description) do
|
||||
|
|
|
@ -761,8 +761,8 @@ defmodule RDF.Dataset do
|
|||
@doc """
|
||||
Returns a nested map of the native Elixir values of a `RDF.Dataset`.
|
||||
|
||||
When the optional `property_map` argument is given, predicates will be mapped
|
||||
to the terms defined in the `RDF.PropertyMap` if present.
|
||||
When a `:context` option is given with a `RDF.PropertyMap`, predicates will
|
||||
be mapped to the terms defined in the `RDF.PropertyMap`, if present.
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -782,15 +782,13 @@ defmodule RDF.Dataset do
|
|||
}
|
||||
|
||||
"""
|
||||
@spec values(t, PropertyMap.t() | nil) :: map
|
||||
def values(dataset, property_map \\ nil)
|
||||
|
||||
def values(%__MODULE__{} = dataset, nil) do
|
||||
@spec values(t, keyword) :: map
|
||||
def values(%__MODULE__{} = dataset, opts \\ []) do
|
||||
if property_map = PropertyMap.from_opts(opts) do
|
||||
map(dataset, Statement.default_property_mapping(property_map))
|
||||
else
|
||||
map(dataset, &Statement.default_term_mapping/1)
|
||||
end
|
||||
|
||||
def values(%__MODULE__{} = dataset, %PropertyMap{} = property_map) do
|
||||
map(dataset, Statement.default_property_mapping(property_map))
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -94,14 +94,6 @@ defmodule RDF.Description do
|
|||
%__MODULE__{description | subject: coerce_subject(new_subject)}
|
||||
end
|
||||
|
||||
defp context(nil), do: nil
|
||||
|
||||
defp context(opts) do
|
||||
if property_map = Keyword.get(opts, :context) do
|
||||
PropertyMap.new(property_map)
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Add statements to a `RDF.Description`.
|
||||
|
||||
|
@ -149,7 +141,7 @@ defmodule RDF.Description do
|
|||
| predications:
|
||||
Map.update(
|
||||
description.predications,
|
||||
coerce_predicate(predicate, context(opts)),
|
||||
coerce_predicate(predicate, PropertyMap.from_opts(opts)),
|
||||
normalized_objects,
|
||||
fn objects ->
|
||||
Map.merge(objects, normalized_objects)
|
||||
|
@ -256,7 +248,7 @@ defmodule RDF.Description do
|
|||
end
|
||||
|
||||
def delete(%__MODULE__{} = description, {predicate, objects}, opts) do
|
||||
predicate = coerce_predicate(predicate, context(opts))
|
||||
predicate = coerce_predicate(predicate, PropertyMap.from_opts(opts))
|
||||
|
||||
if current_objects = Map.get(description.predications, predicate) do
|
||||
normalized_objects =
|
||||
|
@ -661,7 +653,8 @@ defmodule RDF.Description do
|
|||
end
|
||||
|
||||
def include?(%__MODULE__{} = description, {predicate, objects}, opts) do
|
||||
if existing_objects = description.predications[coerce_predicate(predicate, context(opts))] do
|
||||
if existing_objects =
|
||||
description.predications[coerce_predicate(predicate, PropertyMap.from_opts(opts))] do
|
||||
objects
|
||||
|> List.wrap()
|
||||
|> Enum.map(&coerce_object/1)
|
||||
|
@ -726,8 +719,8 @@ defmodule RDF.Description do
|
|||
`RDF.Term.value/1`, or, if you want the subject in an outer map, just put the
|
||||
the description in a graph and use `RDF.Graph.values/2`.
|
||||
|
||||
When the optional `property_map` argument is given, predicates will be mapped
|
||||
to the terms defined in the `RDF.PropertyMap` if present.
|
||||
When a `:context` option is given with a `RDF.PropertyMap`, predicates will
|
||||
be mapped to the terms defined in the `RDF.PropertyMap`, if present.
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -736,19 +729,17 @@ defmodule RDF.Description do
|
|||
%{"http://example.com/p" => ["Foo"]}
|
||||
|
||||
iex> RDF.Description.new(~I<http://example.com/S>, init: {~I<http://example.com/p>, ~L"Foo"})
|
||||
...> |> RDF.Description.values(PropertyMap.new(p: ~I<http://example.com/p>))
|
||||
...> |> RDF.Description.values(context: %{p: ~I<http://example.com/p>})
|
||||
%{p: ["Foo"]}
|
||||
|
||||
"""
|
||||
@spec values(t, PropertyMap.t() | nil) :: map
|
||||
def values(description, property_map \\ nil)
|
||||
|
||||
def values(%__MODULE__{} = description, nil) do
|
||||
@spec values(t, keyword) :: map
|
||||
def values(%__MODULE__{} = description, opts \\ []) do
|
||||
if property_map = PropertyMap.from_opts(opts) do
|
||||
map(description, Statement.default_property_mapping(property_map))
|
||||
else
|
||||
map(description, &Statement.default_term_mapping/1)
|
||||
end
|
||||
|
||||
def values(%__MODULE__{} = description, %PropertyMap{} = property_map) do
|
||||
map(description, Statement.default_property_mapping(property_map))
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -853,8 +853,8 @@ defmodule RDF.Graph do
|
|||
@doc """
|
||||
Returns a nested map of the native Elixir values of a `RDF.Graph`.
|
||||
|
||||
When the optional `property_map` argument is given, predicates will be mapped
|
||||
to the terms defined in the `RDF.PropertyMap` if present.
|
||||
When a `:context` option is given with a `RDF.PropertyMap`, predicates will
|
||||
be mapped to the terms defined in the `RDF.PropertyMap`, if present.
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -872,22 +872,20 @@ defmodule RDF.Graph do
|
|||
...> {~I<http://example.com/S1>, ~I<http://example.com/p>, ~L"Foo"},
|
||||
...> {~I<http://example.com/S2>, ~I<http://example.com/p>, RDF.XSD.integer(42)}
|
||||
...> ])
|
||||
...> |> RDF.Graph.values(PropertyMap.new(p: ~I<http://example.com/p>))
|
||||
...> |> RDF.Graph.values(context: [p: ~I<http://example.com/p>])
|
||||
%{
|
||||
"http://example.com/S1" => %{p: ["Foo"]},
|
||||
"http://example.com/S2" => %{p: [42]}
|
||||
}
|
||||
|
||||
"""
|
||||
@spec values(t, PropertyMap.t() | nil) :: map
|
||||
def values(graph, property_map \\ nil)
|
||||
|
||||
def values(%__MODULE__{} = graph, nil) do
|
||||
@spec values(t, keyword) :: map
|
||||
def values(%__MODULE__{} = graph, opts \\ []) do
|
||||
if property_map = PropertyMap.from_opts(opts) do
|
||||
map(graph, Statement.default_property_mapping(property_map))
|
||||
else
|
||||
map(graph, &Statement.default_term_mapping/1)
|
||||
end
|
||||
|
||||
def values(%__MODULE__{} = graph, %PropertyMap{} = property_map) do
|
||||
map(graph, Statement.default_property_mapping(property_map))
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -23,6 +23,11 @@ defmodule RDF.PropertyMap do
|
|||
property_map
|
||||
end
|
||||
|
||||
@doc false
|
||||
def from_opts(opts)
|
||||
def from_opts(nil), do: nil
|
||||
def from_opts(opts), do: if(property_map = Keyword.get(opts, :context), do: new(property_map))
|
||||
|
||||
def iri(%__MODULE__{} = property_map, term) do
|
||||
Map.get(property_map.iris, coerce_term(term))
|
||||
end
|
||||
|
|
|
@ -97,8 +97,8 @@ defmodule RDF.Quad do
|
|||
@doc """
|
||||
Returns a tuple of native Elixir values from a `RDF.Quad` of RDF terms.
|
||||
|
||||
When the optional `property_map` argument is given, predicates will be mapped
|
||||
to the terms defined in the `RDF.PropertyMap` if present.
|
||||
When a `:context` option is given with a `RDF.PropertyMap`, predicates will
|
||||
be mapped to the terms defined in the `RDF.PropertyMap`, if present.
|
||||
|
||||
Returns `nil` if one of the components of the given tuple is not convertible via `RDF.Term.value/1`.
|
||||
|
||||
|
@ -108,19 +108,17 @@ defmodule RDF.Quad do
|
|||
{"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"}
|
||||
|
||||
iex> {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>}
|
||||
...> |> RDF.Quad.values(PropertyMap.new(p: ~I<http://example.com/p>))
|
||||
...> |> RDF.Quad.values(context: %{p: ~I<http://example.com/p>})
|
||||
{"http://example.com/S", :p, 42, "http://example.com/Graph"}
|
||||
|
||||
"""
|
||||
@spec values(t, PropertyMap.t() | nil) :: t_values | nil
|
||||
def values(quad, property_map \\ nil)
|
||||
|
||||
def values(quad, nil) do
|
||||
@spec values(t, keyword) :: t_values | nil
|
||||
def values(quad, opts \\ []) do
|
||||
if property_map = PropertyMap.from_opts(opts) do
|
||||
map(quad, Statement.default_property_mapping(property_map))
|
||||
else
|
||||
map(quad, &Statement.default_term_mapping/1)
|
||||
end
|
||||
|
||||
def values(quad, %PropertyMap{} = property_map) do
|
||||
map(quad, Statement.default_property_mapping(property_map))
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -99,8 +99,8 @@ defmodule RDF.Statement do
|
|||
@doc """
|
||||
Returns a tuple of native Elixir values from a `RDF.Statement` of RDF terms.
|
||||
|
||||
When the optional `property_map` argument is given, predicates will be mapped
|
||||
to the terms defined in the `RDF.PropertyMap` if present.
|
||||
When a `:context` option is given with a `RDF.PropertyMap`, predicates will
|
||||
be mapped to the terms defined in the `RDF.PropertyMap`, if present.
|
||||
|
||||
Returns `nil` if one of the components of the given tuple is not convertible via `RDF.Term.value/1`.
|
||||
|
||||
|
@ -113,14 +113,14 @@ defmodule RDF.Statement do
|
|||
{"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"}
|
||||
|
||||
iex> {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42)}
|
||||
...> |> RDF.Statement.values(PropertyMap.new(p: ~I<http://example.com/p>))
|
||||
...> |> RDF.Statement.values(context: %{p: ~I<http://example.com/p>})
|
||||
{"http://example.com/S", :p, 42}
|
||||
|
||||
"""
|
||||
@spec values(t, PropertyMap.t() | nil) :: Triple.t_values() | Quad.t_values() | nil
|
||||
def values(quad, property_map \\ nil)
|
||||
def values({_, _, _} = triple, property_map), do: Triple.values(triple, property_map)
|
||||
def values({_, _, _, _} = quad, property_map), do: Quad.values(quad, property_map)
|
||||
@spec values(t, keyword) :: Triple.t_values() | Quad.t_values() | nil
|
||||
def values(quad, opts \\ [])
|
||||
def values({_, _, _} = triple, opts), do: Triple.values(triple, opts)
|
||||
def values({_, _, _, _} = quad, opts), do: Quad.values(quad, opts)
|
||||
|
||||
@doc """
|
||||
Returns a tuple of native Elixir values from a `RDF.Statement` of RDF terms.
|
||||
|
|
|
@ -87,8 +87,8 @@ defmodule RDF.Triple do
|
|||
@doc """
|
||||
Returns a tuple of native Elixir values from a `RDF.Triple` of RDF terms.
|
||||
|
||||
When the optional `property_map` argument is given, predicates will be mapped
|
||||
to the terms defined in the `RDF.PropertyMap` if present.
|
||||
When a `:context` option is given with a `RDF.PropertyMap`, predicates will
|
||||
be mapped to the terms defined in the `RDF.PropertyMap`, if present.
|
||||
|
||||
Returns `nil` if one of the components of the given tuple is not convertible via `RDF.Term.value/1`.
|
||||
|
||||
|
@ -98,20 +98,17 @@ defmodule RDF.Triple do
|
|||
{"http://example.com/S", "http://example.com/p", 42}
|
||||
|
||||
iex> {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42)}
|
||||
...> |> RDF.Triple.values(PropertyMap.new(p: ~I<http://example.com/p>))
|
||||
...> |> RDF.Triple.values(context: %{p: ~I<http://example.com/p>})
|
||||
{"http://example.com/S", :p, 42}
|
||||
|
||||
|
||||
"""
|
||||
@spec values(t, PropertyMap.t() | nil) :: t_values | nil
|
||||
def values(triple, property_map \\ nil)
|
||||
|
||||
def values(triple, nil) do
|
||||
@spec values(t, keyword) :: t_values | nil
|
||||
def values(triple, opts \\ []) do
|
||||
if property_map = PropertyMap.from_opts(opts) do
|
||||
map(triple, Statement.default_property_mapping(property_map))
|
||||
else
|
||||
map(triple, &Statement.default_term_mapping/1)
|
||||
end
|
||||
|
||||
def values(triple, %PropertyMap{} = property_map) do
|
||||
map(triple, Statement.default_property_mapping(property_map))
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -1681,9 +1681,7 @@ defmodule RDF.DatasetTest do
|
|||
end
|
||||
|
||||
test "values/2" do
|
||||
assert Dataset.new([{EX.s1(), EX.p(), EX.o1()}, {EX.s2(), EX.p(), EX.o2(), EX.graph()}])
|
||||
|> Dataset.values(PropertyMap.new(p: EX.p())) ==
|
||||
%{
|
||||
expected_result = %{
|
||||
nil => %{
|
||||
RDF.Term.value(EX.s1()) => %{p: [RDF.Term.value(EX.o1())]}
|
||||
},
|
||||
|
@ -1691,6 +1689,14 @@ defmodule RDF.DatasetTest do
|
|||
RDF.Term.value(EX.s2()) => %{p: [RDF.Term.value(EX.o2())]}
|
||||
}
|
||||
}
|
||||
|
||||
assert Dataset.new([{EX.s1(), EX.p(), EX.o1()}, {EX.s2(), EX.p(), EX.o2(), EX.graph()}])
|
||||
|> Dataset.values(context: PropertyMap.new(p: EX.p())) ==
|
||||
expected_result
|
||||
|
||||
assert Dataset.new([{EX.s1(), EX.p(), EX.o1()}, {EX.s2(), EX.p(), EX.o2(), EX.graph()}])
|
||||
|> Dataset.values(context: %{p: EX.p()}) ==
|
||||
expected_result
|
||||
end
|
||||
|
||||
test "map/2" do
|
||||
|
|
|
@ -844,7 +844,11 @@ defmodule RDF.DescriptionTest do
|
|||
|
||||
test "values/2" do
|
||||
assert Description.new(EX.s(), init: {EX.s(), EX.p(), ~L"Foo"})
|
||||
|> Description.values(PropertyMap.new(p: EX.p())) ==
|
||||
|> Description.values(context: PropertyMap.new(p: EX.p())) ==
|
||||
%{p: ["Foo"]}
|
||||
|
||||
assert Description.new(EX.s(), init: {EX.s(), EX.p(), ~L"Foo"})
|
||||
|> Description.values(context: %{p: EX.p()}) ==
|
||||
%{p: ["Foo"]}
|
||||
end
|
||||
|
||||
|
|
|
@ -1252,12 +1252,18 @@ defmodule RDF.GraphTest do
|
|||
end
|
||||
|
||||
test "values/2" do
|
||||
assert Graph.new([{EX.s1(), EX.p(), EX.o1()}, {EX.s2(), EX.p(), EX.o2()}])
|
||||
|> Graph.values(PropertyMap.new(p: EX.p())) ==
|
||||
%{
|
||||
expected_result = %{
|
||||
RDF.Term.value(EX.s1()) => %{p: [RDF.Term.value(EX.o1())]},
|
||||
RDF.Term.value(EX.s2()) => %{p: [RDF.Term.value(EX.o2())]}
|
||||
}
|
||||
|
||||
assert Graph.new([{EX.s1(), EX.p(), EX.o1()}, {EX.s2(), EX.p(), EX.o2()}])
|
||||
|> Graph.values(context: PropertyMap.new(p: EX.p())) ==
|
||||
expected_result
|
||||
|
||||
assert Graph.new([{EX.s1(), EX.p(), EX.o1()}, {EX.s2(), EX.p(), EX.o2()}])
|
||||
|> Graph.values(context: [p: EX.p()]) ==
|
||||
expected_result
|
||||
end
|
||||
|
||||
test "map/2" do
|
||||
|
|
|
@ -29,20 +29,20 @@ defmodule RDF.QuadTest do
|
|||
assert Quad.values(
|
||||
{~I<http://example.com/S>, ~I<http://example.com/p>, XSD.integer(42),
|
||||
~I<http://example.com/Graph>},
|
||||
PropertyMap.new(p: ~I<http://example.com/p>)
|
||||
context: %{p: ~I<http://example.com/p>}
|
||||
) ==
|
||||
{"http://example.com/S", :p, 42, "http://example.com/Graph"}
|
||||
|
||||
assert Quad.values(
|
||||
{~I<http://example.com/S>, ~I<http://example.com/p>, XSD.integer(42),
|
||||
~I<http://example.com/Graph>},
|
||||
PropertyMap.new()
|
||||
context: PropertyMap.new()
|
||||
) ==
|
||||
{"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"}
|
||||
end
|
||||
|
||||
test "with an invalid RDF.Triple" do
|
||||
refute Quad.values({self(), self(), self(), self()}, PropertyMap.new())
|
||||
refute Quad.values({self(), self(), self(), self()}, context: PropertyMap.new())
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -20,19 +20,25 @@ defmodule RDF.TripleTest do
|
|||
test "with a valid RDF.Triple and RDF.PropertyMap" do
|
||||
assert Triple.values(
|
||||
{~I<http://example.com/S>, ~I<http://example.com/p>, XSD.integer(42)},
|
||||
PropertyMap.new(p: ~I<http://example.com/p>)
|
||||
context: PropertyMap.new(p: ~I<http://example.com/p>)
|
||||
) ==
|
||||
{"http://example.com/S", :p, 42}
|
||||
|
||||
assert Triple.values(
|
||||
{~I<http://example.com/S>, ~I<http://example.com/p>, XSD.integer(42)},
|
||||
PropertyMap.new()
|
||||
context: [p: ~I<http://example.com/p>]
|
||||
) ==
|
||||
{"http://example.com/S", :p, 42}
|
||||
|
||||
assert Triple.values(
|
||||
{~I<http://example.com/S>, ~I<http://example.com/p>, XSD.integer(42)},
|
||||
context: []
|
||||
) ==
|
||||
{"http://example.com/S", "http://example.com/p", 42}
|
||||
end
|
||||
|
||||
test "with an invalid RDF.Triple" do
|
||||
refute Triple.values({self(), self(), self()}, PropertyMap.new())
|
||||
refute Triple.values({self(), self(), self()}, context: PropertyMap.new())
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue