Add prefixed_name/2 and prefixed_name_to_iri/2 to RDF.PrefixMap
This commit is contained in:
parent
bee5e3a81b
commit
a4b71b3f9d
3 changed files with 110 additions and 1 deletions
|
@ -15,11 +15,13 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
|
|||
switched to SPARQL style with the option `:directive_style` and the value `:sparql`
|
||||
- the most common conflict resolution strategies on `RDF.PrefixMap.merge/3` can now
|
||||
be chosen directly with the atoms `:ignore` and `:overwrite`
|
||||
- `RDF.PrefixMap.prefixed_name/2` to convert an IRI to a prefixed name
|
||||
- `RDF.PrefixMap.prefixed_name_to_iri/2` to convert a prefixed name to an IRI
|
||||
|
||||
### Changed
|
||||
|
||||
- when serializing a `RDF.Dataset` with the Turtle encoder the prefixes of all of its graphs
|
||||
are used
|
||||
are used now
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -327,6 +327,65 @@ defmodule RDF.PrefixMap do
|
|||
Map.values(map)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Converts an IRI into a prefixed name.
|
||||
|
||||
Returns `nil` when no prefix for the namespace of `iri` is defined in `prefix_map`.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> RDF.PrefixMap.new(ex: "http://example.com/")
|
||||
...> |> RDF.PrefixMap.prefixed_name(~I<http://example.com/Foo>)
|
||||
"ex:Foo"
|
||||
iex> RDF.PrefixMap.new(ex: "http://example.com/")
|
||||
...> |> RDF.PrefixMap.prefixed_name("http://example.com/Foo")
|
||||
"ex:Foo"
|
||||
|
||||
"""
|
||||
@spec prefixed_name(t, IRI.t() | String.t()) :: String.t() | nil
|
||||
def prefixed_name(prefix_map, iri)
|
||||
|
||||
def prefixed_name(%__MODULE__{} = prefix_map, %IRI{} = iri) do
|
||||
prefixed_name(prefix_map, IRI.to_string(iri))
|
||||
end
|
||||
|
||||
def prefixed_name(%__MODULE__{} = prefix_map, iri) when is_binary(iri) do
|
||||
Enum.find_value(prefix_map, fn {prefix, namespace} ->
|
||||
case String.replace_leading(iri, IRI.to_string(namespace), ":") do
|
||||
^iri ->
|
||||
nil
|
||||
|
||||
truncated_name ->
|
||||
unless String.contains?(truncated_name, ~w[/ #]) do
|
||||
to_string(prefix) <> truncated_name
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Converts a prefixed name into an IRI.
|
||||
|
||||
Returns `nil` when the prefix in `prefixed_name` is not defined in `prefix_map`.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> RDF.PrefixMap.new(ex: "http://example.com/")
|
||||
...> |> RDF.PrefixMap.prefixed_name_to_iri("ex:Foo")
|
||||
~I<http://example.com/Foo>
|
||||
|
||||
"""
|
||||
@spec prefixed_name_to_iri(t, String.t()) :: IRI.t() | nil
|
||||
def prefixed_name_to_iri(%__MODULE__{} = prefix_map, prefixed_name)
|
||||
when is_binary(prefixed_name) do
|
||||
Enum.find_value(prefix_map, fn {prefix, namespace} ->
|
||||
case String.replace_leading(prefixed_name, "#{prefix}:", IRI.to_string(namespace)) do
|
||||
^prefixed_name -> nil
|
||||
iri -> IRI.new(iri)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defimpl Enumerable do
|
||||
def reduce(%RDF.PrefixMap{map: map}, acc, fun), do: Enumerable.reduce(map, acc, fun)
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
defmodule RDF.PrefixMapTest do
|
||||
use RDF.Test.Case
|
||||
|
||||
doctest RDF.PrefixMap
|
||||
|
||||
alias RDF.PrefixMap
|
||||
|
||||
@ex_ns1 ~I<http://example.com/foo/>
|
||||
|
@ -295,6 +297,52 @@ defmodule RDF.PrefixMapTest do
|
|||
assert PrefixMap.namespaces(PrefixMap.new()) == ~w[]a
|
||||
end
|
||||
|
||||
describe "prefixed_name/2" do
|
||||
test "when given an RDF.IRI and the used prefix is defined" do
|
||||
assert PrefixMap.prefixed_name(@example2, ~I<http://example.com/foo/Test>) ==
|
||||
"ex1:Test"
|
||||
|
||||
assert PrefixMap.prefixed_name(@example2, ~I<http://example.com/bar#Test>) ==
|
||||
"ex2:Test"
|
||||
end
|
||||
|
||||
test "when given a string and the used prefix is defined" do
|
||||
assert PrefixMap.prefixed_name(@example2, "http://example.com/foo/Test") ==
|
||||
"ex1:Test"
|
||||
|
||||
assert PrefixMap.prefixed_name(@example2, "http://example.com/bar#Test") ==
|
||||
"ex2:Test"
|
||||
end
|
||||
|
||||
test "when the used prefix is not defined" do
|
||||
assert PrefixMap.prefixed_name(@example2, ~I<http://example.com/fo/Test>) == nil
|
||||
assert PrefixMap.prefixed_name(@example2, "http://example.com/baz#Test") == nil
|
||||
end
|
||||
|
||||
test "when the given IRI is under a sub-path of a defined namespace" do
|
||||
assert PrefixMap.prefixed_name(@example2, ~I<http://example.com/foo/bar/Test>) == nil
|
||||
assert PrefixMap.prefixed_name(@example2, ~I<http://example.com/foo/bar#Test>) == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "prefixed_name_to_iri/2" do
|
||||
test "when the used prefix is defined" do
|
||||
assert PrefixMap.prefixed_name_to_iri(@example2, "ex1:Test") ==
|
||||
~I<http://example.com/foo/Test>
|
||||
|
||||
assert PrefixMap.prefixed_name_to_iri(@example2, "ex2:Test") ==
|
||||
~I<http://example.com/bar#Test>
|
||||
end
|
||||
|
||||
test "when the used prefix is not defined" do
|
||||
assert PrefixMap.prefixed_name_to_iri(@example2, "ex3:Test") == nil
|
||||
end
|
||||
|
||||
test "when the given string does not have a prefix" do
|
||||
assert PrefixMap.prefixed_name_to_iri(@example2, "Test") == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "Enumerable protocol" do
|
||||
test "Enum.count" do
|
||||
assert Enum.count(PrefixMap.new()) == 0
|
||||
|
|
Loading…
Reference in a new issue