rdf-ex/lib/rdf/quad.ex

98 lines
3.8 KiB
Elixir
Raw Normal View History

2017-02-18 20:35:27 +00:00
defmodule RDF.Quad do
@moduledoc """
2017-06-16 20:50:56 +00:00
Helper functions for RDF quads.
2017-02-18 20:35:27 +00:00
2017-06-16 20:50:56 +00:00
A RDF Quad is represented as a plain Elixir tuple consisting of four valid
RDF values for subject, predicate, object and a graph context.
2017-02-18 20:35:27 +00:00
"""
alias RDF.{Statement, Term}
2017-02-18 20:35:27 +00:00
@doc """
Creates a `RDF.Quad` with proper RDF values.
An error is raised when the given elements are not coercible to RDF values.
2017-02-18 20:35:27 +00:00
Note: The `RDF.quad` function is a shortcut to this function.
2017-06-16 22:27:05 +00:00
## Examples
2017-02-18 20:35:27 +00:00
iex> RDF.Quad.new("http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph")
2017-04-10 01:06:20 +00:00
{~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>}
iex> RDF.Quad.new(EX.S, EX.p, 42, EX.Graph)
{RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")}
2017-02-18 20:35:27 +00:00
"""
def new(subject, predicate, object, graph_context) do
{
Statement.coerce_subject(subject),
Statement.coerce_predicate(predicate),
Statement.coerce_object(object),
Statement.coerce_graph_name(graph_context)
2017-02-18 20:35:27 +00:00
}
end
@doc """
Creates a `RDF.Quad` with proper RDF values.
An error is raised when the given elements are not coercible to RDF values.
2017-02-18 20:35:27 +00:00
Note: The `RDF.quad` function is a shortcut to this function.
2017-06-16 22:27:05 +00:00
## Examples
2017-02-18 20:35:27 +00:00
iex> RDF.Quad.new {"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"}
2017-04-10 01:06:20 +00:00
{~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>}
iex> RDF.Quad.new {EX.S, EX.p, 42, EX.Graph}
{RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")}
2017-02-18 20:35:27 +00:00
"""
def new({subject, predicate, object, graph_context}),
do: new(subject, predicate, object, graph_context)
@doc """
Returns a tuple of native Elixir values from a `RDF.Quad` of RDF terms.
Returns `nil` if one of the components of the given tuple is not convertible via `RDF.Term.value/1`.
The optional second argument allows to specify a custom mapping with a function
which will receive a tuple `{statement_position, rdf_term}` where
`statement_position` is one of the atoms `:subject`, `:predicate`, `:object` or
`:graph_name`, while `rdf_term` is the RDF term to be mapped. When the given
function returns `nil` this will be interpreted as an error and will become
the overhaul result of the `values/2` call.
## Examples
iex> RDF.Quad.values {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>}
{"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(fn
...> {:object, object} ->
...> RDF.Term.value(object)
...> {:graph_name, graph_name} ->
...> graph_name
...> {_, resource} ->
...> resource |> to_string() |> String.last() |> String.to_atom()
...> end)
{:S, :p, 42, ~I<http://example.com/Graph>}
"""
def values(quad, mapping \\ &Statement.default_term_mapping/1)
def values({subject, predicate, object, graph_context}, mapping) do
with subject_value when not is_nil(subject_value) <- mapping.({:subject, subject}),
predicate_value when not is_nil(predicate_value) <- mapping.({:predicate, predicate}),
object_value when not is_nil(object_value) <- mapping.({:object, object}),
graph_context_value <- mapping.({:graph_name, graph_context})
do
{subject_value, predicate_value, object_value, graph_context_value}
else
_ -> nil
end
end
def values(_, _), do: nil
2017-02-18 20:35:27 +00:00
end