Add digit_count and fraction_digit_count to RDF.Decimal
This commit is contained in:
parent
3de7d700d3
commit
568190e327
5 changed files with 84 additions and 1 deletions
|
@ -10,6 +10,8 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
|
|||
### Added
|
||||
|
||||
- `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)
|
||||
|
|
|
@ -8,6 +8,7 @@ defmodule RDF.Decimal do
|
|||
|
||||
alias Elixir.Decimal, as: D
|
||||
|
||||
@xsd_integer RDF.Datatype.NS.XSD.integer
|
||||
|
||||
@impl RDF.Datatype
|
||||
def convert(value, opts)
|
||||
|
@ -113,4 +114,37 @@ defmodule RDF.Decimal do
|
|||
@impl RDF.Datatype
|
||||
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
|
||||
|
|
|
@ -73,4 +73,18 @@ defmodule RDF.Integer do
|
|||
@impl RDF.Datatype
|
||||
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
|
||||
|
|
|
@ -122,6 +122,32 @@ defmodule RDF.DecimalTest do
|
|||
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
|
||||
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"-42E+3") == ~d"-42000.0"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -76,6 +76,14 @@ defmodule RDF.IntegerTest do
|
|||
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
|
||||
test "two literals are equal when they have the same datatype and lexical form" do
|
||||
|
|
Loading…
Reference in a new issue