From 60206b5bc690b6884d6fd890c09f48c761f882ee Mon Sep 17 00:00:00 2001 From: Michael Thomas Date: Thu, 13 Sep 2018 19:58:24 +0100 Subject: [PATCH 1/6] Added numeric types --- .../eu/timepit/refined/types/numeric.scala | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala index 5653bb94a..340b762d4 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala @@ -6,6 +6,46 @@ import eu.timepit.refined.numeric.{Negative, NonNegative, NonPositive, Positive} /** Module for numeric refined types. */ object numeric { + /** An `Byte` in the range from 1 to `Byte.MaxValue`. */ + type PosByte = Byte Refined Positive + + object PosByte extends RefinedTypeOps.Numeric[PosByte, Byte] + + /** An `Byte` in the range from 0 to `Byte.MaxValue`. */ + type NonNegByte = Byte Refined NonNegative + + object NonNegByte extends RefinedTypeOps.Numeric[NonNegByte, Byte] + + /** An `Byte` in the range from `Byte.MinValue` to -1. */ + type NegByte = Byte Refined Negative + + object NegByte extends RefinedTypeOps.Numeric[NegByte, Byte] + + /** An `Byte` in the range from `Byte.MinValue` to 0. */ + type NonPosByte = Byte Refined NonPositive + + object NonPosByte extends RefinedTypeOps.Numeric[NonPosByte, Byte] + + /** An `Short` in the range from 1 to `Short.MaxValue`. */ + type PosShort = Short Refined Positive + + object PosShort extends RefinedTypeOps.Numeric[PosShort, Short] + + /** An `Short` in the range from 0 to `Short.MaxValue`. */ + type NonNegShort = Short Refined NonNegative + + object NonNegShort extends RefinedTypeOps.Numeric[NonNegShort, Short] + + /** An `Short` in the range from `Short.MinValue` to -1. */ + type NegShort = Short Refined Negative + + object NegShort extends RefinedTypeOps.Numeric[NegShort, Short] + + /** An `Short` in the range from `Short.MinValue` to 0. */ + type NonPosShort = Short Refined NonPositive + + object NonPosShort extends RefinedTypeOps.Numeric[NonPosShort, Short] + /** An `Int` in the range from 1 to `Int.MaxValue`. */ type PosInt = Int Refined Positive @@ -46,6 +86,26 @@ object numeric { object NonPosLong extends RefinedTypeOps.Numeric[NonPosLong, Long] + /** A `BigInt` greater than 0. */ + type PosBigInt = BigInt Refined Positive + + object PosBigInt extends RefinedTypeOps[PosBigInt, BigInt] + + /** A `BigInt` greater than or equal to 0. */ + type NonNegBigInt = BigInt Refined NonNegative + + object NonNegBigInt extends RefinedTypeOps[NonNegBigInt, BigInt] + + /** A `BigInt` less than or equal to 0. */ + type NegBigInt = BigInt Refined Negative + + object NegBigInt extends RefinedTypeOps[NegBigInt, BigInt] + + /** A `BigInt` less than or equal to 0. */ + type NonPosBigInt = BigInt Refined NonPositive + + object NonPosBigInt extends RefinedTypeOps[NonPosBigInt, BigInt] + /** A `Float` greater than 0. */ type PosFloat = Float Refined Positive @@ -85,9 +145,53 @@ object numeric { type NonPosDouble = Double Refined NonPositive object NonPosDouble extends RefinedTypeOps.Numeric[NonPosDouble, Double] + + /** A `BigDecimal` greater than 0. */ + type PosBigDecimal = BigDecimal Refined Positive + + object PosBigDecimal extends RefinedTypeOps[PosBigDecimal, BigDecimal] + + /** A `BigDecimal` greater than or equal to 0. */ + type NonNegBigDecimal = BigDecimal Refined NonNegative + + object NonNegBigDecimal extends RefinedTypeOps[NonNegBigDecimal, BigDecimal] + + /** A `BigDecimal` less than 0. */ + type NegBigDecimal = BigDecimal Refined Negative + + object NegBigDecimal extends RefinedTypeOps[NegBigDecimal, BigDecimal] + + /** A `BigDecimal` less than or equal to 0. */ + type NonPosBigDecimal = BigDecimal Refined NonPositive + + object NonPosBigDecimal extends RefinedTypeOps[NonPosBigDecimal, BigDecimal] } trait NumericTypes { + final type PosByte = numeric.PosByte + final val PosByte = numeric.PosByte + + final type NonNegByte = numeric.NonNegByte + final val NonNegByte = numeric.NonNegByte + + final type NegByte = numeric.NegByte + final val NegByte = numeric.NegByte + + final type NonPosByte = numeric.NonPosByte + final val NonPosByte = numeric.NonPosByte + + final type PosShort = numeric.PosShort + final val PosShort = numeric.PosShort + + final type NonNegShort = numeric.NonNegShort + final val NonNegShort = numeric.NonNegShort + + final type NegShort = numeric.NegShort + final val NegShort = numeric.NegShort + + final type NonPosShort = numeric.NonPosShort + final val NonPosShort = numeric.NonPosShort + final type PosInt = numeric.PosInt final val PosInt = numeric.PosInt @@ -103,6 +207,18 @@ trait NumericTypes { final type PosLong = numeric.PosLong final val PosLong = numeric.PosLong + final type PosBigInt = numeric.PosBigInt + final val PosBigInt = numeric.PosBigInt + + final type NonNegBigInt = numeric.NonNegBigInt + final val NonNegBigInt = numeric.NonNegBigInt + + final type NegBigInt = numeric.NegBigInt + final val NegBigInt = numeric.NegBigInt + + final type NonPosBigInt = numeric.NonPosBigInt + final val NonPosBigInt = numeric.NonPosBigInt + final type NonNegLong = numeric.NonNegLong final val NonNegLong = numeric.NonNegLong @@ -135,4 +251,16 @@ trait NumericTypes { final type NonPosDouble = numeric.NonPosDouble final val NonPosDouble = numeric.NonPosDouble + + final type PosBigDecimal = numeric.PosBigDecimal + final val PosBigDecimal = numeric.PosBigDecimal + + final type NonNegBigDecimal = numeric.NonNegBigDecimal + final val NonNegBigDecimal = numeric.NonNegBigDecimal + + final type NegBigDecimal = numeric.NegBigDecimal + final val NegBigDecimal = numeric.NegBigDecimal + + final type NonPosBigDecimal = numeric.NonPosBigDecimal + final val NonPosBigDecimal = numeric.NonPosBigDecimal } From 5036c66fd633d2b1b4e2a415525817f2c64e9494 Mon Sep 17 00:00:00 2001 From: Michael Thomas Date: Thu, 13 Sep 2018 20:02:33 +0100 Subject: [PATCH 2/6] Corrected typo --- .../scala/eu/timepit/refined/types/numeric.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala index 340b762d4..d0f72a978 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala @@ -6,42 +6,42 @@ import eu.timepit.refined.numeric.{Negative, NonNegative, NonPositive, Positive} /** Module for numeric refined types. */ object numeric { - /** An `Byte` in the range from 1 to `Byte.MaxValue`. */ + /** A `Byte` in the range from 1 to `Byte.MaxValue`. */ type PosByte = Byte Refined Positive object PosByte extends RefinedTypeOps.Numeric[PosByte, Byte] - /** An `Byte` in the range from 0 to `Byte.MaxValue`. */ + /** A `Byte` in the range from 0 to `Byte.MaxValue`. */ type NonNegByte = Byte Refined NonNegative object NonNegByte extends RefinedTypeOps.Numeric[NonNegByte, Byte] - /** An `Byte` in the range from `Byte.MinValue` to -1. */ + /** A `Byte` in the range from `Byte.MinValue` to -1. */ type NegByte = Byte Refined Negative object NegByte extends RefinedTypeOps.Numeric[NegByte, Byte] - /** An `Byte` in the range from `Byte.MinValue` to 0. */ + /** A `Byte` in the range from `Byte.MinValue` to 0. */ type NonPosByte = Byte Refined NonPositive object NonPosByte extends RefinedTypeOps.Numeric[NonPosByte, Byte] - /** An `Short` in the range from 1 to `Short.MaxValue`. */ + /** A `Short` in the range from 1 to `Short.MaxValue`. */ type PosShort = Short Refined Positive object PosShort extends RefinedTypeOps.Numeric[PosShort, Short] - /** An `Short` in the range from 0 to `Short.MaxValue`. */ + /** A `Short` in the range from 0 to `Short.MaxValue`. */ type NonNegShort = Short Refined NonNegative object NonNegShort extends RefinedTypeOps.Numeric[NonNegShort, Short] - /** An `Short` in the range from `Short.MinValue` to -1. */ + /** A `Short` in the range from `Short.MinValue` to -1. */ type NegShort = Short Refined Negative object NegShort extends RefinedTypeOps.Numeric[NegShort, Short] - /** An `Short` in the range from `Short.MinValue` to 0. */ + /** A `Short` in the range from `Short.MinValue` to 0. */ type NonPosShort = Short Refined NonPositive object NonPosShort extends RefinedTypeOps.Numeric[NonPosShort, Short] From a922b5c426ab04e192588376bdfffb80e42e034e Mon Sep 17 00:00:00 2001 From: Michael Thomas Date: Thu, 13 Sep 2018 21:46:41 +0100 Subject: [PATCH 3/6] Binary compatibility fix attempt --- .../src/main/scala/eu/timepit/refined/types/numeric.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala index d0f72a978..cce4ad600 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala @@ -167,7 +167,7 @@ object numeric { object NonPosBigDecimal extends RefinedTypeOps[NonPosBigDecimal, BigDecimal] } -trait NumericTypes { +trait NumericTypes extends NumericTypesBinCompat1 { final type PosByte = numeric.PosByte final val PosByte = numeric.PosByte @@ -215,7 +215,9 @@ trait NumericTypes { final type NegBigInt = numeric.NegBigInt final val NegBigInt = numeric.NegBigInt +} +trait NumericTypesBinCompat1 { final type NonPosBigInt = numeric.NonPosBigInt final val NonPosBigInt = numeric.NonPosBigInt From b4a66d98bc882eb916780ed38e8a88573a8ddd2b Mon Sep 17 00:00:00 2001 From: Michael Thomas Date: Fri, 14 Sep 2018 18:02:47 +0100 Subject: [PATCH 4/6] Binary compatibility fix --- .../scala/eu/timepit/refined/types/all.scala | 4 +- .../eu/timepit/refined/types/numeric.scala | 78 +++++++++---------- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/types/all.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/types/all.scala index 0128cec7c..7b359fde3 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/types/all.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/types/all.scala @@ -1,7 +1,7 @@ package eu.timepit.refined.types /** Module for all predefined refined types. */ -object all extends AllTypes +object all extends AllTypes with AllTypesBinCompat1 trait AllTypes extends CharTypes @@ -10,3 +10,5 @@ trait AllTypes with NumericTypes with StringTypes with TimeTypes + +trait AllTypesBinCompat1 extends NumericTypesBinCompat1 \ No newline at end of file diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala index cce4ad600..0448af8f3 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/types/numeric.scala @@ -167,31 +167,7 @@ object numeric { object NonPosBigDecimal extends RefinedTypeOps[NonPosBigDecimal, BigDecimal] } -trait NumericTypes extends NumericTypesBinCompat1 { - final type PosByte = numeric.PosByte - final val PosByte = numeric.PosByte - - final type NonNegByte = numeric.NonNegByte - final val NonNegByte = numeric.NonNegByte - - final type NegByte = numeric.NegByte - final val NegByte = numeric.NegByte - - final type NonPosByte = numeric.NonPosByte - final val NonPosByte = numeric.NonPosByte - - final type PosShort = numeric.PosShort - final val PosShort = numeric.PosShort - - final type NonNegShort = numeric.NonNegShort - final val NonNegShort = numeric.NonNegShort - - final type NegShort = numeric.NegShort - final val NegShort = numeric.NegShort - - final type NonPosShort = numeric.NonPosShort - final val NonPosShort = numeric.NonPosShort - +trait NumericTypes { final type PosInt = numeric.PosInt final val PosInt = numeric.PosInt @@ -207,20 +183,6 @@ trait NumericTypes extends NumericTypesBinCompat1 { final type PosLong = numeric.PosLong final val PosLong = numeric.PosLong - final type PosBigInt = numeric.PosBigInt - final val PosBigInt = numeric.PosBigInt - - final type NonNegBigInt = numeric.NonNegBigInt - final val NonNegBigInt = numeric.NonNegBigInt - - final type NegBigInt = numeric.NegBigInt - final val NegBigInt = numeric.NegBigInt -} - -trait NumericTypesBinCompat1 { - final type NonPosBigInt = numeric.NonPosBigInt - final val NonPosBigInt = numeric.NonPosBigInt - final type NonNegLong = numeric.NonNegLong final val NonNegLong = numeric.NonNegLong @@ -253,6 +215,44 @@ trait NumericTypesBinCompat1 { final type NonPosDouble = numeric.NonPosDouble final val NonPosDouble = numeric.NonPosDouble +} + +trait NumericTypesBinCompat1 { + final type PosByte = numeric.PosByte + final val PosByte = numeric.PosByte + + final type NonNegByte = numeric.NonNegByte + final val NonNegByte = numeric.NonNegByte + + final type NegByte = numeric.NegByte + final val NegByte = numeric.NegByte + + final type NonPosByte = numeric.NonPosByte + final val NonPosByte = numeric.NonPosByte + + final type PosShort = numeric.PosShort + final val PosShort = numeric.PosShort + + final type NonNegShort = numeric.NonNegShort + final val NonNegShort = numeric.NonNegShort + + final type NegShort = numeric.NegShort + final val NegShort = numeric.NegShort + + final type NonPosShort = numeric.NonPosShort + final val NonPosShort = numeric.NonPosShort + + final type PosBigInt = numeric.PosBigInt + final val PosBigInt = numeric.PosBigInt + + final type NonNegBigInt = numeric.NonNegBigInt + final val NonNegBigInt = numeric.NonNegBigInt + + final type NegBigInt = numeric.NegBigInt + final val NegBigInt = numeric.NegBigInt + + final type NonPosBigInt = numeric.NonPosBigInt + final val NonPosBigInt = numeric.NonPosBigInt final type PosBigDecimal = numeric.PosBigDecimal final val PosBigDecimal = numeric.PosBigDecimal From 5630a8ee1101a54023df9445b7716c319f913d62 Mon Sep 17 00:00:00 2001 From: Michael Thomas Date: Fri, 14 Sep 2018 18:13:34 +0100 Subject: [PATCH 5/6] Formatting fix --- .../shared/src/main/scala/eu/timepit/refined/types/all.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/types/all.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/types/all.scala index 7b359fde3..b0cbcaaed 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/types/all.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/types/all.scala @@ -11,4 +11,4 @@ trait AllTypes with StringTypes with TimeTypes -trait AllTypesBinCompat1 extends NumericTypesBinCompat1 \ No newline at end of file +trait AllTypesBinCompat1 extends NumericTypesBinCompat1 From 620d418bc61afe80d020cbce6bcfcd172c3f8ee3 Mon Sep 17 00:00:00 2001 From: Michael Thomas Date: Fri, 14 Sep 2018 20:06:23 +0100 Subject: [PATCH 6/6] Tests added --- .../refined/types/NumericTypesSpec.scala | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/modules/core/shared/src/test/scala/eu/timepit/refined/types/NumericTypesSpec.scala b/modules/core/shared/src/test/scala/eu/timepit/refined/types/NumericTypesSpec.scala index 968544839..3a0e575a3 100644 --- a/modules/core/shared/src/test/scala/eu/timepit/refined/types/NumericTypesSpec.scala +++ b/modules/core/shared/src/test/scala/eu/timepit/refined/types/NumericTypesSpec.scala @@ -6,6 +6,70 @@ import org.scalacheck.Properties class NumericTypesSpec extends Properties("NumericTypes") { + property("PosByte.from(1)") = secure { + PosByte.from(1).isRight + } + + property("PosByte.from(0)") = secure { + PosByte.from(0) ?= Left("Predicate failed: (0 > 0).") + } + + property("NonNegByte.from(0)") = secure { + NonNegByte.from(0).isRight + } + + property("NonNegByte.from(-1)") = secure { + NonNegByte.from(-1) ?= Left("Predicate (-1 < 0) did not fail.") + } + + property("NegByte.from(-1)") = secure { + NegByte.from(-1).isRight + } + + property("NegByte.from(0)") = secure { + NegByte.from(0) ?= Left("Predicate failed: (0 < 0).") + } + + property("NonPosByte.from(0)") = secure { + NonPosByte.from(0).isRight + } + + property("NonPosByte.from(1)") = secure { + NonPosByte.from(1) ?= Left("Predicate (1 > 0) did not fail.") + } + + property("PosShort.from(1)") = secure { + PosShort.from(1).isRight + } + + property("PosShort.from(0)") = secure { + PosShort.from(0) ?= Left("Predicate failed: (0 > 0).") + } + + property("NonNegShort.from(0)") = secure { + NonNegShort.from(0).isRight + } + + property("NonNegShort.from(-1)") = secure { + NonNegShort.from(-1) ?= Left("Predicate (-1 < 0) did not fail.") + } + + property("NegShort.from(-1)") = secure { + NegShort.from(-1).isRight + } + + property("NegShort.from(0)") = secure { + NegShort.from(0) ?= Left("Predicate failed: (0 < 0).") + } + + property("NonPosShort.from(0)") = secure { + NonPosShort.from(0).isRight + } + + property("NonPosShort.from(1)") = secure { + NonPosShort.from(1) ?= Left("Predicate (1 > 0) did not fail.") + } + property("PosInt.from(1)") = secure { PosInt.from(1).isRight } @@ -70,6 +134,38 @@ class NumericTypesSpec extends Properties("NumericTypes") { NonPosLong.from(1L) ?= Left("Predicate (1 > 0) did not fail.") } + property("PosBigInt.from(BigInt(1))") = secure { + PosBigInt.from(BigInt(1)).isRight + } + + property("PosBigInt.from(BigInt(0))") = secure { + PosBigInt.from(BigInt(0)) ?= Left("Predicate failed: (0 > 0).") + } + + property("NonNegBigInt.from(BigInt(0))") = secure { + NonNegBigInt.from(BigInt(0)).isRight + } + + property("NonNegBigInt.from(BigInt(-1))") = secure { + NonNegBigInt.from(BigInt(-1)) ?= Left("Predicate (-1 < 0) did not fail.") + } + + property("NegBigInt.from(BigInt(-1))") = secure { + NegBigInt.from(BigInt(-1)).isRight + } + + property("NegBigInt.from(BigInt(0))") = secure { + NegBigInt.from(BigInt(0)) ?= Left("Predicate failed: (0 < 0).") + } + + property("NonPosBigInt.from(BigInt(0))") = secure { + NonPosBigInt.from(BigInt(0)).isRight + } + + property("NonPosBigInt.from(BigInt(1))") = secure { + NonPosBigInt.from(BigInt(1)) ?= Left("Predicate (1 > 0) did not fail.") + } + property("PosFloat.from(0.1F)") = secure { PosFloat.from(0.1f).isRight } @@ -133,4 +229,36 @@ class NumericTypesSpec extends Properties("NumericTypes") { property("NonPosDouble.from(0.1)") = secure { NonPosDouble.from(0.1).isLeft } + + property("PosBigDecimal.from(BigDecimal(0.1))") = secure { + PosBigDecimal.from(BigDecimal(0.1)).isRight + } + + property("PosBigDecimal.from(BigDecimal(0.0))") = secure { + PosBigDecimal.from(BigDecimal(0.0)).isLeft + } + + property("NonNegBigDecimal.from(BigDecimal(0.0))") = secure { + NonNegBigDecimal.from(BigDecimal(0.0)).isRight + } + + property("NonNegBigDecimal.from(BigDecimal(-0.1))") = secure { + NonNegBigDecimal.from(BigDecimal(-0.1)).isLeft + } + + property("NegBigDecimal.from(BigDecimal(-0.1))") = secure { + NegBigDecimal.from(BigDecimal(-0.1)).isRight + } + + property("NegBigDecimal.from(BigDecimal(0.0))") = secure { + NegBigDecimal.from(BigDecimal(0.0)).isLeft + } + + property("NonPosBigDecimal.from(BigDecimal(0.0))") = secure { + NonPosBigDecimal.from(BigDecimal(0.0)).isRight + } + + property("NonPosBigDecimal.from(BigDecimal(0.1))") = secure { + NonPosBigDecimal.from(BigDecimal(0.1)).isLeft + } }