Add update/2 functions to RDF.Literal and the datatypes
This commit is contained in:
parent
238c9310be
commit
060fac4675
6 changed files with 72 additions and 0 deletions
|
@ -254,6 +254,10 @@ defmodule RDF.Literal do
|
|||
def matches?(value, pattern, flags) when is_binary(value) and is_binary(pattern) and is_binary(flags),
|
||||
do: XSD.Utils.Regex.matches?(value, pattern, flags)
|
||||
|
||||
def update(%__MODULE__{literal: %datatype{} = literal}, fun, opts \\ []) do
|
||||
Datatype.Registry.rdf_datatype(datatype).update(literal, fun, opts)
|
||||
end
|
||||
|
||||
defimpl String.Chars do
|
||||
def to_string(literal) do
|
||||
String.Chars.to_string(literal.literal)
|
||||
|
|
|
@ -85,4 +85,7 @@ defmodule RDF.Literal.Datatype do
|
|||
them is invalid.
|
||||
"""
|
||||
@callback compare(Literal.t() | literal, Literal.t() | literal) :: comparison_result | :indeterminate | nil
|
||||
|
||||
@callback update(Literal.t() | literal, fun()) :: Literal.t
|
||||
@callback update(Literal.t() | literal, fun(), keyword) :: Literal.t
|
||||
end
|
||||
|
|
|
@ -107,6 +107,16 @@ defmodule RDF.Literal.Generic do
|
|||
|
||||
def compare(_, _), do: nil
|
||||
|
||||
@impl Datatype
|
||||
def update(literal, fun, opts \\ [])
|
||||
def update(%Literal{literal: literal}, fun, opts), do: update(literal, fun, opts)
|
||||
def update(%__MODULE__{} = literal, fun, _opts) do
|
||||
literal
|
||||
|> value()
|
||||
|> fun.()
|
||||
|> new(datatype: literal.datatype)
|
||||
end
|
||||
|
||||
defimpl String.Chars do
|
||||
def to_string(literal) do
|
||||
literal.value
|
||||
|
|
|
@ -112,6 +112,16 @@ defmodule RDF.LangString do
|
|||
|
||||
def compare(_, _), do: nil
|
||||
|
||||
@impl Datatype
|
||||
def update(literal, fun, opts \\ [])
|
||||
def update(%Literal{literal: literal}, fun, opts), do: update(literal, fun, opts)
|
||||
def update(%__MODULE__{} = literal, fun, _opts) do
|
||||
literal
|
||||
|> value()
|
||||
|> fun.()
|
||||
|> new(language: literal.language)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if a language tagged string literal or language tag matches a language range.
|
||||
|
||||
|
|
|
@ -97,6 +97,18 @@ defmodule RDF.Literal.XSD do
|
|||
def compare(%unquote(xsd_datatype){} = left, right) do
|
||||
unquote(xsd_datatype).compare(left, right)
|
||||
end
|
||||
|
||||
@impl RDF.Literal.Datatype
|
||||
def update(literal, fun, opts \\ [])
|
||||
def update(%Literal{literal: literal}, fun, opts), do: update(literal, fun, opts)
|
||||
def update(%unquote(xsd_datatype){} = literal, fun, opts) do
|
||||
case Keyword.get(opts, :as) do
|
||||
:lexical -> lexical(literal)
|
||||
nil -> value(literal)
|
||||
end
|
||||
|> fun.()
|
||||
|> new()
|
||||
end
|
||||
end
|
||||
| datatype_specific_module_body(xsd_datatype)]
|
||||
end
|
||||
|
|
|
@ -402,6 +402,39 @@ defmodule RDF.LiteralTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "update/2" do
|
||||
test "it updates value and lexical form" do
|
||||
assert RDF.string("foo")
|
||||
|> Literal.update(fn s when is_binary(s) -> s <> "bar" end) ==
|
||||
RDF.string("foobar")
|
||||
assert RDF.integer(1) |> Literal.update(fn i when is_integer(i) -> i + 1 end) ==
|
||||
RDF.integer(2)
|
||||
assert RDF.byte(42) |> Literal.update(fn i when is_integer(i) -> i + 1 end) ==
|
||||
RDF.byte(43)
|
||||
assert RDF.integer(1)
|
||||
|> Literal.update(fn i when is_integer(i) -> "0" <> to_string(i) end) ==
|
||||
RDF.integer("01")
|
||||
end
|
||||
|
||||
test "it does not change the datatype of generic literals" do
|
||||
assert RDF.literal("foo", datatype: "http://example.com/dt")
|
||||
|> Literal.update(fn s when is_binary(s) -> s <> "bar" end) ==
|
||||
RDF.literal("foobar", datatype: "http://example.com/dt")
|
||||
end
|
||||
|
||||
test "it does not change the language of language literals" do
|
||||
assert RDF.langString("foo", language: "en")
|
||||
|> Literal.update(fn s when is_binary(s) -> s <> "bar" end) ==
|
||||
RDF.langString("foobar", language: "en")
|
||||
end
|
||||
|
||||
test "with as: :lexical opt it passes the lexical form" do
|
||||
assert RDF.integer(1)
|
||||
|> Literal.update(fn i when is_binary(i) -> "0" <> i end, as: :lexical) ==
|
||||
RDF.integer("01")
|
||||
end
|
||||
end
|
||||
|
||||
describe "String.Chars protocol implementation" do
|
||||
test "with XSD.Datatype literal" do
|
||||
assert Literal.new("foo") |> to_string() == "foo"
|
||||
|
|
Loading…
Reference in a new issue