Fix some issues with RDF.Term coercion in various contexts
This commit is contained in:
parent
1cd3a0c342
commit
f4877bbc65
5 changed files with 73 additions and 15 deletions
|
@ -216,7 +216,7 @@ defmodule RDF.Datatype do
|
|||
end
|
||||
|
||||
def equal_value?(%RDF.Literal{} = left, right) when not is_nil(right) do
|
||||
unless RDF.term?(right) do
|
||||
unless RDF.Term.term?(right) do
|
||||
equal_value?(left, RDF.Term.coerce(right))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -79,7 +79,7 @@ defmodule RDF.Numeric do
|
|||
end
|
||||
|
||||
def equal_value?(%RDF.Literal{} = left, right) when not is_nil(right) do
|
||||
unless RDF.term?(right) do
|
||||
unless RDF.Term.term?(right) do
|
||||
equal_value?(left, RDF.Term.coerce(right))
|
||||
end
|
||||
end
|
||||
|
@ -269,7 +269,7 @@ defmodule RDF.Numeric do
|
|||
end
|
||||
|
||||
def abs(value) do
|
||||
unless RDF.term?(value) do
|
||||
if not is_nil(value) and not RDF.Term.term?(value) do
|
||||
value
|
||||
|> RDF.Term.coerce()
|
||||
|> abs()
|
||||
|
@ -331,7 +331,7 @@ defmodule RDF.Numeric do
|
|||
end
|
||||
|
||||
def round(value, precision) do
|
||||
unless RDF.term?(value) do
|
||||
if not is_nil(value) and not RDF.Term.term?(value) do
|
||||
value
|
||||
|> RDF.Term.coerce()
|
||||
|> round(precision)
|
||||
|
@ -383,7 +383,7 @@ defmodule RDF.Numeric do
|
|||
end
|
||||
|
||||
def ceil(value) do
|
||||
unless RDF.term?(value) do
|
||||
if not is_nil(value) and not RDF.Term.term?(value) do
|
||||
value
|
||||
|> RDF.Term.coerce()
|
||||
|> ceil()
|
||||
|
@ -430,7 +430,7 @@ defmodule RDF.Numeric do
|
|||
end
|
||||
|
||||
def floor(value) do
|
||||
unless RDF.term?(value) do
|
||||
if not is_nil(value) and not RDF.Term.term?(value) do
|
||||
value
|
||||
|> RDF.Term.coerce()
|
||||
|> floor()
|
||||
|
@ -450,14 +450,24 @@ defmodule RDF.Numeric do
|
|||
end
|
||||
end
|
||||
|
||||
defp arithmetic_operation(op, %Literal{} = arg1, arg2, fun),
|
||||
do: arithmetic_operation(op, arg1, RDF.Term.coerce(arg2), fun)
|
||||
defp arithmetic_operation(op, %Literal{} = arg1, arg2, fun) do
|
||||
if not is_nil(arg2) and not RDF.Term.term?(arg2) do
|
||||
arithmetic_operation(op, arg1, RDF.Term.coerce(arg2), fun)
|
||||
end
|
||||
end
|
||||
|
||||
defp arithmetic_operation(op, arg1, %Literal{} = arg2, fun),
|
||||
do: arithmetic_operation(op, RDF.Term.coerce(arg1), arg2, fun)
|
||||
defp arithmetic_operation(op, arg1, %Literal{} = arg2, fun) do
|
||||
if not is_nil(arg1) and not RDF.Term.term?(arg1) do
|
||||
arithmetic_operation(op, RDF.Term.coerce(arg1), arg2, fun)
|
||||
end
|
||||
end
|
||||
|
||||
defp arithmetic_operation(op, arg1, arg2, fun),
|
||||
do: arithmetic_operation(op, RDF.Term.coerce(arg1), RDF.Term.coerce(arg2), fun)
|
||||
defp arithmetic_operation(op, arg1, arg2, fun) do
|
||||
if not is_nil(arg1) and not RDF.Term.term?(arg1) and
|
||||
not is_nil(arg2) and not RDF.Term.term?(arg2) do
|
||||
arithmetic_operation(op, RDF.Term.coerce(arg1), RDF.Term.coerce(arg2), fun)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
defp type_conversion(%Literal{datatype: datatype} = arg1,
|
||||
|
|
|
@ -251,7 +251,7 @@ defmodule RDF.Literal do
|
|||
do: RDF.IRI.equal_value?(left, right)
|
||||
|
||||
def equal_value?(%RDF.Literal{} = left, right) when not is_nil(right) do
|
||||
unless RDF.term?(right) do
|
||||
unless RDF.Term.term?(right) do
|
||||
equal_value?(left, RDF.Term.coerce(right))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,27 @@ defprotocol RDF.Term do
|
|||
@type t :: RDF.IRI.t | RDF.BlankNode.t | RDF.Literal.t
|
||||
|
||||
|
||||
@doc """
|
||||
Checks if the given value is a RDF term.
|
||||
|
||||
Note: As opposed to `RDF.term?` this function returns false on atoms and does
|
||||
not try resolves those to IRIs.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> RDF.Term.term?(RDF.iri("http://example.com/resource"))
|
||||
true
|
||||
iex> RDF.Term.term?(EX.Resource)
|
||||
false
|
||||
iex> RDF.Term.term?(RDF.bnode)
|
||||
true
|
||||
iex> RDF.Term.term?(RDF.integer(42))
|
||||
true
|
||||
iex> RDF.Term.term?(42)
|
||||
false
|
||||
"""
|
||||
def term?(value)
|
||||
|
||||
@doc """
|
||||
Tests for term equality.
|
||||
|
||||
|
@ -51,24 +72,28 @@ defimpl RDF.Term, for: RDF.IRI do
|
|||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.IRI.equal_value?(term1, term2)
|
||||
def coerce(term), do: term
|
||||
def term?(_), do: true
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: RDF.BlankNode do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.BlankNode.equal_value?(term1, term2)
|
||||
def coerce(term), do: term
|
||||
def term?(_), do: true
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: Reference do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.BlankNode.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: RDF.Literal do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Literal.equal_value?(term1, term2)
|
||||
def coerce(term), do: term
|
||||
def term?(_), do: true
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: Atom do
|
||||
|
@ -80,58 +105,69 @@ defimpl RDF.Term, for: Atom do
|
|||
def coerce(true), do: RDF.true
|
||||
def coerce(false), do: RDF.false
|
||||
def coerce(_), do: nil
|
||||
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: BitString do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.String.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: Integer do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.Integer.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: Float do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.Double.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: Decimal do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.Decimal.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: DateTime do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.DateTime.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: NaiveDateTime do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.DateTime.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: Date do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.Date.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: Time do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(term1, term2), do: RDF.Term.equal_value?(coerce(term1), term2)
|
||||
def coerce(term), do: RDF.Time.new(term)
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
||||
defimpl RDF.Term, for: Any do
|
||||
def equal?(term1, term2), do: term1 == term2
|
||||
def equal_value?(_, _), do: nil
|
||||
def coerce(_), do: nil
|
||||
def term?(_), do: false
|
||||
end
|
||||
|
|
|
@ -104,6 +104,10 @@ defmodule RDF.NumericTest do
|
|||
assert Numeric.add(3.14, 42) == RDF.double(45.14)
|
||||
assert RDF.decimal(3.14) |> Numeric.add(42) == RDF.decimal(45.14)
|
||||
assert Numeric.add(42, RDF.decimal(3.14)) == RDF.decimal(45.14)
|
||||
assert Numeric.add(42, ~B"foo") == nil
|
||||
assert Numeric.add(42, :foo) == nil
|
||||
assert Numeric.add(:foo, 42) == nil
|
||||
assert Numeric.add(:foo, :bar) == nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -339,6 +343,9 @@ defmodule RDF.NumericTest do
|
|||
assert Numeric.divide("foo", "bar") == nil
|
||||
assert Numeric.divide(4, "bar") == nil
|
||||
assert Numeric.divide("foo", 2) == nil
|
||||
assert Numeric.divide(42, :bar) == nil
|
||||
assert Numeric.divide(:foo, 42) == nil
|
||||
assert Numeric.divide(:foo, :bar) == nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -383,6 +390,7 @@ defmodule RDF.NumericTest do
|
|||
assert Numeric.abs(-3.14) == RDF.double(3.14)
|
||||
assert Numeric.abs(D.new(-3.14)) == RDF.decimal(3.14)
|
||||
assert Numeric.abs("foo") == nil
|
||||
assert Numeric.abs(:foo) == nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -419,6 +427,7 @@ defmodule RDF.NumericTest do
|
|||
assert Numeric.round(-3.14) == RDF.double(-3.0)
|
||||
assert Numeric.round(D.new(3.14)) == RDF.decimal("3")
|
||||
assert Numeric.round("foo") == nil
|
||||
assert Numeric.round(:foo) == nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -459,6 +468,7 @@ defmodule RDF.NumericTest do
|
|||
assert Numeric.round(-3.14, 1) == RDF.double(-3.1)
|
||||
assert Numeric.round(D.new(3.14), 1) == RDF.decimal("3.1")
|
||||
assert Numeric.round("foo", 1) == nil
|
||||
assert Numeric.round(:foo, 1) == nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -493,6 +503,7 @@ defmodule RDF.NumericTest do
|
|||
assert Numeric.ceil(-3.14) == RDF.double("-3")
|
||||
assert Numeric.ceil(D.new(3.14)) == RDF.decimal("4")
|
||||
assert Numeric.ceil("foo") == nil
|
||||
assert Numeric.ceil(:foo) == nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -527,6 +538,7 @@ defmodule RDF.NumericTest do
|
|||
assert Numeric.floor(-3.14) == RDF.double("-4")
|
||||
assert Numeric.floor(D.new(3.14)) == RDF.decimal("3")
|
||||
assert Numeric.floor("foo") == nil
|
||||
assert Numeric.floor(:foo) == nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue