diff --git a/modules/refined4s-core/shared/src/main/scala/refined4s/CanBeOrdered.scala b/modules/refined4s-core/shared/src/main/scala/refined4s/CanBeOrdered.scala new file mode 100644 index 0000000..091d322 --- /dev/null +++ b/modules/refined4s-core/shared/src/main/scala/refined4s/CanBeOrdered.scala @@ -0,0 +1,16 @@ +package refined4s + +/** @author Kevin Lee + * @since 2023-12-29 + */ +trait CanBeOrdered[A: Ordering] { + self: NewtypeBase[A] => + + given derivedOrdering: Ordering[Type] = deriving[Ordering] + + given derivedToOrdered: Conversion[Type, Ordered[Type]] with { + def apply(a: Type): Ordered[Type] = + Ordered.orderingToOrdered[Type](a)(using derivedOrdering) + } + +} diff --git a/modules/refined4s-core/shared/src/test/scala/refined4s/CanBeOrderedSpec.scala b/modules/refined4s-core/shared/src/test/scala/refined4s/CanBeOrderedSpec.scala new file mode 100644 index 0000000..6527eff --- /dev/null +++ b/modules/refined4s-core/shared/src/test/scala/refined4s/CanBeOrderedSpec.scala @@ -0,0 +1,42 @@ +package refined4s + +import hedgehog.* +import hedgehog.runner.* + +/** @author Kevin Lee + * @since 2023-12-29 + */ +object CanBeOrderedSpec extends Properties { + override def tests: List[Test] = List( + property("test Ordering from CanBeOrdered", testOrdering), + property("test Ordered from CanBeOrdered", testOrdered), + ) + + def testOrdering: Property = + for { + n1 <- Gen.int(Range.linear(Int.MinValue, Int.MaxValue)).log("n1") + n2 <- Gen.int(Range.linear(Int.MinValue, Int.MaxValue)).log("n2") + } yield { + val input1 = MyNum(n1) + val input2 = MyNum(n2) + + val expected = n1.compare(n2) + Result.diff(input1, input2)(Ordering[MyNum].compare(_, _) == expected) + } + + def testOrdered: Property = + for { + n1 <- Gen.int(Range.linear(Int.MinValue, Int.MaxValue)).log("n1") + n2 <- Gen.int(Range.linear(Int.MinValue, Int.MaxValue)).log("n2") + } yield { + val input1 = MyNum(n1) + val input2 = MyNum(n2) + + val expected = n1.compare(n2) + Result.diff(input1, input2: MyNum)(_.compare(_) == expected) + } + + type MyNum = MyNum.Type + object MyNum extends Newtype[Int], CanBeOrdered[Int] + +}