Add digit_count and fraction_digit_count to RDF.Decimal

This commit is contained in:
Marcel Otto 2019-04-22 11:17:16 +02:00
parent 3de7d700d3
commit 568190e327
5 changed files with 84 additions and 1 deletions

View file

@ -10,6 +10,8 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
### Added ### Added
- `RDF.Literal.matches?/3` for XQuery regex pattern matching - `RDF.Literal.matches?/3` for XQuery regex pattern matching
- `RDF.Decimal.digit_count/1` and `RDF.Decimal.fraction_digit_count/1` for
determining the number of digits of decimal literals
[Compare v0.6.0...HEAD](https://github.com/marcelotto/rdf-ex/compare/v0.6.0...HEAD) [Compare v0.6.0...HEAD](https://github.com/marcelotto/rdf-ex/compare/v0.6.0...HEAD)

View file

@ -8,6 +8,7 @@ defmodule RDF.Decimal do
alias Elixir.Decimal, as: D alias Elixir.Decimal, as: D
@xsd_integer RDF.Datatype.NS.XSD.integer
@impl RDF.Datatype @impl RDF.Datatype
def convert(value, opts) def convert(value, opts)
@ -113,4 +114,37 @@ defmodule RDF.Decimal do
@impl RDF.Datatype @impl RDF.Datatype
def compare(left, right), do: RDF.Numeric.compare(left, right) def compare(left, right), do: RDF.Numeric.compare(left, right)
@doc """
The number of digits in the XML Schema canonical form of the literal value.
"""
def digit_count(%RDF.Literal{datatype: @id} = literal) do
if valid?(literal) do
literal
|> canonical()
|> lexical()
|> String.replace(".", "")
|> String.replace("-", "")
|> String.length()
end
end
def digit_count(%RDF.Literal{datatype: @xsd_integer} = literal),
do: RDF.Integer.digit_count(literal)
@doc """
The number of digits to the right of the decimal point in the XML Schema canonical form of the literal value.
"""
def fraction_digit_count(%RDF.Literal{datatype: @id, value: value} = literal) do
if valid?(literal) do
[_, fraction] =
literal
|> canonical()
|> lexical()
|> String.split(".")
String.length(fraction)
end
end
def fraction_digit_count(%RDF.Literal{datatype: @xsd_integer}), do: 0
end end

View file

@ -73,4 +73,18 @@ defmodule RDF.Integer do
@impl RDF.Datatype @impl RDF.Datatype
def compare(left, right), do: RDF.Numeric.compare(left, right) def compare(left, right), do: RDF.Numeric.compare(left, right)
@doc """
The number of digits in the XML Schema canonical form of the literal value.
"""
def digit_count(%RDF.Literal{datatype: @id} = literal) do
if valid?(literal) do
literal
|> canonical()
|> lexical()
|> String.replace("-", "")
|> String.length()
end
end
end end

View file

@ -122,6 +122,32 @@ defmodule RDF.DecimalTest do
end end
end end
test "digit_count/1" do
assert RDF.Decimal.digit_count(RDF.decimal("1.2345")) == 5
assert RDF.Decimal.digit_count(RDF.decimal("-1.2345")) == 5
assert RDF.Decimal.digit_count(RDF.decimal("+1.2345")) == 5
assert RDF.Decimal.digit_count(RDF.decimal("01.23450")) == 5
assert RDF.Decimal.digit_count(RDF.decimal("01.23450")) == 5
assert RDF.Decimal.digit_count(RDF.decimal("NAN")) == nil
assert RDF.Decimal.digit_count(RDF.integer("2")) == 1
assert RDF.Decimal.digit_count(RDF.integer("23")) == 2
assert RDF.Decimal.digit_count(RDF.integer("023")) == 2
end
test "fraction_digit_count/1" do
assert RDF.Decimal.fraction_digit_count(RDF.decimal("1.2345")) == 4
assert RDF.Decimal.fraction_digit_count(RDF.decimal("-1.2345")) == 4
assert RDF.Decimal.fraction_digit_count(RDF.decimal("+1.2345")) == 4
assert RDF.Decimal.fraction_digit_count(RDF.decimal("01.23450")) == 4
assert RDF.Decimal.fraction_digit_count(RDF.decimal("0.023450")) == 5
assert RDF.Decimal.fraction_digit_count(RDF.decimal("NAN")) == nil
assert RDF.Decimal.fraction_digit_count(RDF.integer("2")) == 0
assert RDF.Decimal.fraction_digit_count(RDF.integer("23")) == 0
assert RDF.Decimal.fraction_digit_count(RDF.integer("023")) == 0
end
defmacrop sigil_d(str, _opts) do defmacrop sigil_d(str, _opts) do
quote do quote do
@ -151,5 +177,4 @@ defmodule RDF.DecimalTest do
assert Decimal.canonical_decimal(~d"1.2E3") == ~d"1200.0" assert Decimal.canonical_decimal(~d"1.2E3") == ~d"1200.0"
assert Decimal.canonical_decimal(~d"-42E+3") == ~d"-42000.0" assert Decimal.canonical_decimal(~d"-42E+3") == ~d"-42000.0"
end end
end end

View file

@ -76,6 +76,14 @@ defmodule RDF.IntegerTest do
end end
end end
test "digit_count/1" do
assert RDF.Integer.digit_count(RDF.integer("2")) == 1
assert RDF.Integer.digit_count(RDF.integer("23")) == 2
assert RDF.Integer.digit_count(RDF.integer("023")) == 2
assert RDF.Integer.digit_count(RDF.integer("+023")) == 2
assert RDF.Integer.digit_count(RDF.integer("-023")) == 2
assert RDF.Integer.digit_count(RDF.integer("NaN")) == nil
end
describe "equality" do describe "equality" do
test "two literals are equal when they have the same datatype and lexical form" do test "two literals are equal when they have the same datatype and lexical form" do