Add RDF.Guards.maybe_ns_term/1
This commit is contained in:
parent
00a6103e56
commit
24051c6153
8 changed files with 66 additions and 32 deletions
1
.iex.exs
1
.iex.exs
|
@ -1,4 +1,5 @@
|
|||
import RDF.Sigils
|
||||
import RDF.Guards
|
||||
|
||||
alias RDF.NS
|
||||
alias RDF.NS.{RDFS, OWL, SKOS}
|
||||
|
|
|
@ -41,6 +41,7 @@ defmodule RDF do
|
|||
alias RDF.{IRI, Namespace, Literal, BlankNode, Triple, Quad,
|
||||
Description, Graph, Dataset, PrefixMap}
|
||||
|
||||
import RDF.Guards
|
||||
import RDF.Utils.Bootstrapping
|
||||
|
||||
defdelegate default_base_iri(), to: RDF.IRI, as: :default_base
|
||||
|
@ -146,8 +147,8 @@ defmodule RDF do
|
|||
def resource?(value)
|
||||
def resource?(%IRI{}), do: true
|
||||
def resource?(%BlankNode{}), do: true
|
||||
def resource?(atom) when is_atom(atom) and atom not in ~w[true false nil]a do
|
||||
resource?(Namespace.resolve_term(atom))
|
||||
def resource?(qname) when maybe_ns_term(qname) do
|
||||
resource?(Namespace.resolve_term(qname))
|
||||
rescue
|
||||
RDF.Namespace.UndefinedTermError -> false
|
||||
end
|
||||
|
|
4
lib/rdf/guards.ex
Normal file
4
lib/rdf/guards.ex
Normal file
|
@ -0,0 +1,4 @@
|
|||
defmodule RDF.Guards do
|
||||
defguard maybe_ns_term(term)
|
||||
when is_atom(term) and term not in [nil, true, false]
|
||||
end
|
|
@ -17,6 +17,7 @@ defmodule RDF.IRI do
|
|||
"""
|
||||
|
||||
alias RDF.Namespace
|
||||
import RDF.Guards
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
value: String.t
|
||||
|
@ -49,11 +50,10 @@ defmodule RDF.IRI do
|
|||
"""
|
||||
@spec new(coercible) :: t
|
||||
def new(iri)
|
||||
def new(iri) when is_binary(iri), do: %__MODULE__{value: iri}
|
||||
def new(qname) when is_atom(qname) and qname not in [nil, true, false],
|
||||
do: Namespace.resolve_term(qname)
|
||||
def new(%URI{} = uri), do: uri |> URI.to_string |> new
|
||||
def new(%__MODULE__{} = iri), do: iri
|
||||
def new(iri) when is_binary(iri), do: %__MODULE__{value: iri}
|
||||
def new(qname) when maybe_ns_term(qname), do: Namespace.resolve_term(qname)
|
||||
def new(%URI{} = uri), do: uri |> URI.to_string |> new
|
||||
def new(%__MODULE__{} = iri), do: iri
|
||||
|
||||
@doc """
|
||||
Creates a `RDF.IRI`, but checks if the given IRI is valid.
|
||||
|
@ -64,11 +64,10 @@ defmodule RDF.IRI do
|
|||
"""
|
||||
@spec new!(coercible) :: t
|
||||
def new!(iri)
|
||||
def new!(iri) when is_binary(iri), do: iri |> valid!() |> new()
|
||||
def new!(qname) when is_atom(qname) and qname not in [nil, true, false],
|
||||
do: new(qname) # since terms of a namespace are already validated
|
||||
def new!(%URI{} = uri), do: uri |> valid!() |> new()
|
||||
def new!(%__MODULE__{} = iri), do: valid!(iri)
|
||||
def new!(iri) when is_binary(iri), do: iri |> valid!() |> new()
|
||||
def new!(qname) when maybe_ns_term(qname), do: new(qname) # since terms of a namespace are already validated
|
||||
def new!(%URI{} = uri), do: uri |> valid!() |> new()
|
||||
def new!(%__MODULE__{} = iri), do: valid!(iri)
|
||||
|
||||
|
||||
@doc """
|
||||
|
@ -80,7 +79,7 @@ defmodule RDF.IRI do
|
|||
@spec coerce_base(coercible) :: t
|
||||
def coerce_base(base_iri)
|
||||
|
||||
def coerce_base(module) when is_atom(module) do
|
||||
def coerce_base(module) when maybe_ns_term(module) do
|
||||
if RDF.Vocabulary.Namespace.vocabulary_namespace?(module) do
|
||||
apply(module, :__base_iri__, [])
|
||||
|> new()
|
||||
|
@ -139,7 +138,7 @@ defmodule RDF.IRI do
|
|||
def absolute?(%__MODULE__{value: value}), do: absolute?(value)
|
||||
def absolute?(%URI{scheme: nil}), do: false
|
||||
def absolute?(%URI{scheme: _}), do: true
|
||||
def absolute?(qname) when is_atom(qname) and qname not in [nil, true, false] do
|
||||
def absolute?(qname) when maybe_ns_term(qname) do
|
||||
qname |> Namespace.resolve_term |> absolute?()
|
||||
rescue
|
||||
_ -> false
|
||||
|
@ -198,9 +197,9 @@ defmodule RDF.IRI do
|
|||
"""
|
||||
@spec scheme(coercible) :: String.t | nil
|
||||
def scheme(iri)
|
||||
def scheme(%__MODULE__{value: value}), do: scheme(value)
|
||||
def scheme(%URI{scheme: scheme}), do: scheme
|
||||
def scheme(qname) when is_atom(qname), do: Namespace.resolve_term(qname) |> scheme()
|
||||
def scheme(%__MODULE__{value: value}), do: scheme(value)
|
||||
def scheme(%URI{scheme: scheme}), do: scheme
|
||||
def scheme(qname) when maybe_ns_term(qname), do: Namespace.resolve_term(qname) |> scheme()
|
||||
def scheme(iri) when is_binary(iri) do
|
||||
with [_, scheme] <- Regex.run(@scheme_regex, iri) do
|
||||
scheme
|
||||
|
@ -213,11 +212,10 @@ defmodule RDF.IRI do
|
|||
"""
|
||||
@spec parse(coercible) :: URI.t
|
||||
def parse(iri)
|
||||
def parse(iri) when is_binary(iri), do: URI.parse(iri)
|
||||
def parse(qname) when is_atom(qname) and qname not in [nil, true, false],
|
||||
do: Namespace.resolve_term(qname) |> parse()
|
||||
def parse(%__MODULE__{value: value}), do: URI.parse(value)
|
||||
def parse(%URI{} = uri), do: uri
|
||||
def parse(iri) when is_binary(iri), do: URI.parse(iri)
|
||||
def parse(qname) when maybe_ns_term(qname), do: Namespace.resolve_term(qname) |> parse()
|
||||
def parse(%__MODULE__{value: value}), do: URI.parse(value)
|
||||
def parse(%URI{} = uri), do: uri
|
||||
|
||||
|
||||
@doc """
|
||||
|
@ -264,7 +262,7 @@ defmodule RDF.IRI do
|
|||
def to_string(%__MODULE__{value: value}),
|
||||
do: value
|
||||
|
||||
def to_string(qname) when is_atom(qname),
|
||||
def to_string(qname) when maybe_ns_term(qname),
|
||||
do: qname |> new() |> __MODULE__.to_string()
|
||||
|
||||
defimpl String.Chars do
|
||||
|
|
|
@ -9,6 +9,8 @@ defmodule RDF.List do
|
|||
|
||||
alias RDF.{BlankNode, Description, Graph, IRI}
|
||||
|
||||
import RDF.Guards
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
head: IRI.t,
|
||||
graph: Graph.t
|
||||
|
@ -34,7 +36,7 @@ defmodule RDF.List do
|
|||
@spec new(IRI.coercible, Graph.t) :: t
|
||||
def new(head, graph)
|
||||
|
||||
def new(head, graph) when is_atom(head) and head not in ~w[true false nil]a,
|
||||
def new(head, graph) when maybe_ns_term(head),
|
||||
do: new(RDF.iri(head), graph)
|
||||
|
||||
def new(head, graph) do
|
||||
|
@ -85,7 +87,7 @@ defmodule RDF.List do
|
|||
{RDF.nil, graph}
|
||||
end
|
||||
|
||||
defp do_from(list, head, graph, opts) when is_atom(head) do
|
||||
defp do_from(list, head, graph, opts) when maybe_ns_term(head) do
|
||||
do_from(list, RDF.iri!(head), graph, opts)
|
||||
end
|
||||
|
||||
|
@ -186,8 +188,7 @@ defmodule RDF.List do
|
|||
def node?(%IRI{} = list_node, graph),
|
||||
do: do_node?(list_node, graph)
|
||||
|
||||
def node?(list_node, graph)
|
||||
when is_atom(list_node) and list_node not in ~w[true false nil]a,
|
||||
def node?(list_node, graph) when maybe_ns_term(list_node),
|
||||
do: do_node?(RDF.iri(list_node), graph)
|
||||
|
||||
def node?(_, _), do: false
|
||||
|
|
|
@ -9,6 +9,8 @@ defmodule RDF.Namespace do
|
|||
|
||||
alias RDF.IRI
|
||||
|
||||
import RDF.Guards
|
||||
|
||||
@doc """
|
||||
Resolves a term to a `RDF.IRI`.
|
||||
"""
|
||||
|
@ -32,7 +34,7 @@ defmodule RDF.Namespace do
|
|||
|
||||
def resolve_term(%IRI{} = iri), do: iri
|
||||
|
||||
def resolve_term(namespaced_term) when is_atom(namespaced_term) do
|
||||
def resolve_term(namespaced_term) when maybe_ns_term(namespaced_term) do
|
||||
namespaced_term
|
||||
|> to_string()
|
||||
|> do_resolve_term()
|
||||
|
|
|
@ -6,6 +6,7 @@ defmodule RDF.Statement do
|
|||
"""
|
||||
|
||||
alias RDF.{BlankNode, IRI, Literal, Quad, Term, Triple}
|
||||
import RDF.Guards
|
||||
|
||||
@type subject :: IRI.t | BlankNode.t
|
||||
@type predicate :: IRI.t | BlankNode.t
|
||||
|
@ -47,7 +48,7 @@ defmodule RDF.Statement do
|
|||
def coerce_subject(iri = %IRI{}), do: iri
|
||||
def coerce_subject(bnode = %BlankNode{}), do: bnode
|
||||
def coerce_subject("_:" <> identifier), do: RDF.bnode(identifier)
|
||||
def coerce_subject(iri) when is_atom(iri) or is_binary(iri), do: RDF.iri!(iri)
|
||||
def coerce_subject(iri) when maybe_ns_term(iri) or is_binary(iri), do: RDF.iri!(iri)
|
||||
def coerce_subject(arg), do: raise RDF.Triple.InvalidSubjectError, subject: arg
|
||||
|
||||
@doc false
|
||||
|
@ -58,7 +59,7 @@ defmodule RDF.Statement do
|
|||
# them, by introducing the notion of "generalized RDF".
|
||||
# TODO: Support an option `:strict_rdf` to explicitly disallow them or produce warnings or ...
|
||||
def coerce_predicate(bnode = %BlankNode{}), do: bnode
|
||||
def coerce_predicate(iri) when is_atom(iri) or is_binary(iri), do: RDF.iri!(iri)
|
||||
def coerce_predicate(iri) when maybe_ns_term(iri) or is_binary(iri), do: RDF.iri!(iri)
|
||||
def coerce_predicate(arg), do: raise RDF.Triple.InvalidPredicateError, predicate: arg
|
||||
|
||||
@doc false
|
||||
|
@ -68,7 +69,7 @@ defmodule RDF.Statement do
|
|||
def coerce_object(literal = %Literal{}), do: literal
|
||||
def coerce_object(bnode = %BlankNode{}), do: bnode
|
||||
def coerce_object(bool) when is_boolean(bool), do: Literal.new(bool)
|
||||
def coerce_object(atom) when is_atom(atom), do: RDF.iri(atom)
|
||||
def coerce_object(atom) when maybe_ns_term(atom), do: RDF.iri(atom)
|
||||
def coerce_object(arg), do: Literal.new(arg)
|
||||
|
||||
@doc false
|
||||
|
@ -78,7 +79,7 @@ defmodule RDF.Statement do
|
|||
def coerce_graph_name(iri = %IRI{}), do: iri
|
||||
def coerce_graph_name(bnode = %BlankNode{}), do: bnode
|
||||
def coerce_graph_name("_:" <> identifier), do: RDF.bnode(identifier)
|
||||
def coerce_graph_name(iri) when is_atom(iri) or is_binary(iri), do: RDF.iri!(iri)
|
||||
def coerce_graph_name(iri) when maybe_ns_term(iri) or is_binary(iri), do: RDF.iri!(iri)
|
||||
def coerce_graph_name(arg),
|
||||
do: raise RDF.Quad.InvalidGraphContextError, graph_context: arg
|
||||
|
||||
|
|
26
test/unit/guards_test.exs
Normal file
26
test/unit/guards_test.exs
Normal file
|
@ -0,0 +1,26 @@
|
|||
defmodule RDF.GuardsTest do
|
||||
use RDF.Test.Case
|
||||
|
||||
doctest RDF.Guards
|
||||
|
||||
import RDF.Guards
|
||||
|
||||
describe "maybe_ns_term/1" do
|
||||
def test_fun(term) when maybe_ns_term(term), do: true
|
||||
def test_fun(_), do: false
|
||||
|
||||
test "with booleans" do
|
||||
refute test_fun(true)
|
||||
refute test_fun(false)
|
||||
end
|
||||
|
||||
test "with nil" do
|
||||
refute test_fun(nil)
|
||||
end
|
||||
|
||||
test "any other atom" do
|
||||
assert test_fun(:foo)
|
||||
assert test_fun(Foo)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue