Add RDF.IRI.in_namespace?/2

This commit is contained in:
Marcel Otto 2020-11-10 10:56:38 +01:00
parent 3806269d3e
commit 42d5dfc5a6
3 changed files with 39 additions and 8 deletions

View file

@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
- `RDF.Dataset.prefixes/1` for getting an aggregated `RDF.PrefixMap` over all graphs
- `RDF.PrefixMap.put/3` for adding a prefix mapping and overwrite an existing one
- `RDF.BlankNode.value/1` for getting the internal string representation of a blank node
- `RDF.IRI.in_namespace?/2` for determining whether an IRI lies in a namespace
### Changed

View file

@ -50,7 +50,7 @@ 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 maybe_ns_term(qname), do: Namespace.resolve_term!(qname)
def new(term) when maybe_ns_term(term), do: Namespace.resolve_term!(term)
def new(%URI{} = uri), do: uri |> URI.to_string() |> new
def new(%__MODULE__{} = iri), do: iri
@ -65,7 +65,7 @@ defmodule RDF.IRI do
def new!(iri)
def new!(iri) when is_binary(iri), do: iri |> valid!() |> new()
# since terms of a namespace are already validated
def new!(qname) when maybe_ns_term(qname), do: new(qname)
def new!(term) when maybe_ns_term(term), do: new(term)
def new!(%URI{} = uri), do: uri |> valid!() |> new()
def new!(%__MODULE__{} = iri), do: valid!(iri)
@ -162,8 +162,8 @@ defmodule RDF.IRI do
def absolute?(%URI{scheme: nil}), do: false
def absolute?(%URI{scheme: _}), do: true
def absolute?(qname) when maybe_ns_term(qname) do
case Namespace.resolve_term(qname) do
def absolute?(term) when maybe_ns_term(term) do
case Namespace.resolve_term(term) do
{:ok, iri} -> absolute?(iri)
_ -> false
end
@ -222,7 +222,7 @@ defmodule RDF.IRI do
def scheme(iri)
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(term) when maybe_ns_term(term), do: Namespace.resolve_term!(term) |> scheme()
def scheme(iri) when is_binary(iri) do
with [_, scheme] <- Regex.run(@scheme_regex, iri) do
@ -236,10 +236,30 @@ 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 maybe_ns_term(qname), do: Namespace.resolve_term!(qname) |> parse()
def parse(term) when maybe_ns_term(term), do: Namespace.resolve_term!(term) |> parse()
def parse(%__MODULE__{value: value}), do: URI.parse(value)
def parse(%URI{} = uri), do: uri
@doc """
Checks whether `iri` lies in `namespace`.
"""
@spec in_namespace?(t | module, String.t() | t | module) :: boolean
def in_namespace?(iri, namespace)
def in_namespace?(%__MODULE__{value: value}, namespace) when is_binary(namespace),
do: String.starts_with?(value, namespace)
def in_namespace?(term, namespace) when maybe_ns_term(term),
do: term |> Namespace.resolve_term!() |> in_namespace?(namespace)
def in_namespace?(iri, namespace) when maybe_ns_term(namespace),
do: in_namespace?(iri, coerce_base(namespace))
def in_namespace?(iri, %__MODULE__{} = namespace),
do: in_namespace?(iri, __MODULE__.to_string(namespace))
# def in_namespace?(_, _), do: false
@doc """
Tests for value equality of IRIs.
@ -294,8 +314,8 @@ defmodule RDF.IRI do
def to_string(%__MODULE__{value: value}),
do: value
def to_string(qname) when maybe_ns_term(qname),
do: qname |> new() |> __MODULE__.to_string()
def to_string(term) when maybe_ns_term(term),
do: term |> new() |> __MODULE__.to_string()
defimpl String.Chars do
def to_string(iri), do: RDF.IRI.to_string(iri)

View file

@ -339,6 +339,16 @@ defmodule RDF.IRITest do
end
end
test "in_namespace?/2" do
assert IRI.in_namespace?(IRI.new("http://example.com/foo"), "http://example.com/")
assert IRI.in_namespace?(IRI.new("http://example.com/foo#bar"), "http://example.com/foo#")
assert IRI.in_namespace?(IRI.new("http://example.com/foo"), IRI.new("http://example.com/"))
assert IRI.in_namespace?(EX.Foo, IRI.new("http://example.com/#"))
assert IRI.in_namespace?(IRI.new("http://example.com/#foo"), EX)
assert IRI.in_namespace?(EX.foo(), EX)
assert IRI.in_namespace?(EX.Foo, EX)
end
describe "to_string/1" do
test "with IRIs" do
assert IRI.to_string(IRI.new("http://example.com/")) == "http://example.com/"