Skip to content

Commit

Permalink
Merge pull request #1193 from mrdziuban/remove-shapeless-scala-3
Browse files Browse the repository at this point in the history
Remove shapeless dependency in scala 3
  • Loading branch information
fthomas authored Jun 15, 2023
2 parents 10387aa + 00dcf50 commit e2a1640
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 67 deletions.
6 changes: 5 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,12 @@ lazy val core = myCrossProject("core")
scalaOrganization.value % "scala-reflect" % scalaVersion.value,
scalaOrganization.value % "scala-compiler" % scalaVersion.value
)
) ++ (
if (isScala3Setting.value)
Seq()
else
Seq("com.chuusai" %%% "shapeless" % shapelessVersion)
) ++ Seq(
("com.chuusai" %%% "shapeless" % shapelessVersion).cross(CrossVersion.for3Use2_13),
"org.scalacheck" %%% "scalacheck" % scalaCheckVersion % Test
)
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package eu.timepit.refined.api

import eu.timepit.refined.internal._
import shapeless.tag.@@

/**
* Type class that allows `F` to be used as carrier type of a refinement.
Expand Down Expand Up @@ -92,18 +91,6 @@ object RefType {
Refined.unsafeApply(ta.value)
}

implicit val tagRefType: RefType[@@] =
new RefType[@@] {
override def unsafeWrap[T, P](t: T): T @@ P =
t.asInstanceOf[T @@ P]

override def unwrap[T, P](tp: T @@ P): T =
tp

override def unsafeRewrap[T, A, B](ta: T @@ A): T @@ B =
ta.asInstanceOf[T @@ B]
}

final class RefTypeOps[F[_, _], T, P](tp: F[T, P])(implicit F: RefType[F]) {
def unwrap: T =
F.unwrap(tp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import eu.timepit.refined.api._
import eu.timepit.refined.api.Inference.==>
import eu.timepit.refined.boolean._
import eu.timepit.refined.internal.Resources
import shapeless.{::, HList, HNil}

/** Module for logical predicates. */
object boolean extends BooleanInference0 {
Expand Down Expand Up @@ -178,20 +177,20 @@ object boolean extends BooleanInference0 {
}

object AllOf {
implicit def allOfHNilValidate[T]: Validate.Plain[T, AllOf[HNil]] =
Validate.alwaysPassed(AllOf(HList()))
implicit def allOfEmptyTupleValidate[T]: Validate.Plain[T, AllOf[EmptyTuple]] =
Validate.alwaysPassed(AllOf(EmptyTuple))

implicit def allOfHConsValidate[T, PH, RH, PT <: HList, RT <: HList](implicit
implicit def allOfTupleConsValidate[T, PH, RH, PT <: Tuple, RT <: Tuple](implicit
vh: Validate.Aux[T, PH, RH],
vt: Validate.Aux[T, AllOf[PT], AllOf[RT]]
): Validate.Aux[T, AllOf[PH :: PT], AllOf[vh.Res :: RT]] =
new Validate[T, AllOf[PH :: PT]] {
override type R = AllOf[vh.Res :: RT]
): Validate.Aux[T, AllOf[PH *: PT], AllOf[vh.Res *: RT]] =
new Validate[T, AllOf[PH *: PT]] {
override type R = AllOf[vh.Res *: RT]

override def validate(t: T): Res = {
val rh = vh.validate(t)
val rt = vt.validate(t)
Result.fromBoolean(rh.isPassed && rt.isPassed, AllOf(rh :: rt.detail.ps))
Result.fromBoolean(rh.isPassed && rt.isPassed, AllOf(rh *: rt.detail.ps))
}

override def showExpr(t: T): String =
Expand All @@ -203,20 +202,20 @@ object boolean extends BooleanInference0 {
}

object AnyOf {
implicit def anyOfHNilValidate[T]: Validate.Plain[T, AnyOf[HNil]] =
Validate.alwaysFailed(AnyOf(HList()))
implicit def anyOfEmptyTupleValidate[T]: Validate.Plain[T, AnyOf[EmptyTuple]] =
Validate.alwaysFailed(AnyOf(EmptyTuple))

implicit def anyOfHConsValidate[T, PH, RH, PT <: HList, RT <: HList](implicit
implicit def anyOfHConsValidate[T, PH, RH, PT <: Tuple, RT <: Tuple](implicit
vh: Validate.Aux[T, PH, RH],
vt: Validate.Aux[T, AnyOf[PT], AnyOf[RT]]
): Validate.Aux[T, AnyOf[PH :: PT], AnyOf[vh.Res :: RT]] =
new Validate[T, AnyOf[PH :: PT]] {
override type R = AnyOf[vh.Res :: RT]
): Validate.Aux[T, AnyOf[PH *: PT], AnyOf[vh.Res *: RT]] =
new Validate[T, AnyOf[PH *: PT]] {
override type R = AnyOf[vh.Res *: RT]

override def validate(t: T): Res = {
val rh = vh.validate(t)
val rt = vt.validate(t)
Result.fromBoolean(rh.isPassed || rt.isPassed, AnyOf(rh :: rt.detail.ps))
Result.fromBoolean(rh.isPassed || rt.isPassed, AnyOf(rh *: rt.detail.ps))
}

override def showExpr(t: T): String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import eu.timepit.refined.collection._
import eu.timepit.refined.generic.Equal
import eu.timepit.refined.internal.Resources
import eu.timepit.refined.numeric.{GreaterEqual, Interval}
import shapeless.Witness
import shapeless.nat.{_0, _1}

/** Module for collection predicates. */
object collection extends CollectionInference {
Expand Down Expand Up @@ -87,7 +85,7 @@ object collection extends CollectionInference {
* Predicate that checks if the size of an `Iterable` is less than
* or equal to `N`.
*/
type MaxSize[N] = Size[Interval.Closed[_0, N]]
type MaxSize[N] = Size[Interval.Closed[0, N]]

/** Predicate that checks if an `Iterable` is not empty. */
type NonEmpty = Not[Empty]
Expand Down Expand Up @@ -179,7 +177,7 @@ object collection extends CollectionInference {
implicit def indexValidate[A, P, R, N <: Int, T](implicit
v: Validate.Aux[A, P, R],
ev: T => PartialFunction[Int, A],
wn: Witness.Aux[N]
wn: ValueOf[N]
): Validate.Aux[T, Index[N, P], Index[N, Option[v.Res]]] =
new Validate[T, Index[N, P]] {
override type R = Index[N, Option[v.Res]]
Expand Down Expand Up @@ -344,7 +342,7 @@ private[refined] trait CollectionInference {
p1.adapt("sizeInference(%s)")

implicit def sizeGreaterEqual1NonEmptyInference[A](implicit
p1: A ==> GreaterEqual[_1]
p1: A ==> GreaterEqual[1]
): Size[A] ==> NonEmpty =
p1.adapt("sizeGreaterEqual1NonEmptyInference(%s)")
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package eu.timepit.refined.internal

import scala.compiletime.erasedValue
import shapeless.{_0, Nat, Succ}
import scala.compiletime.ops.int.S

trait ToInt[N <: Nat] {
trait ToInt[N <: Int] {
def apply(): Int
}

object ToInt {
def apply[N <: Nat](implicit toInt: ToInt[N]): ToInt[N] = toInt
def apply[N <: Int](implicit toInt: ToInt[N]): ToInt[N] = toInt

inline implicit def materialize[N <: Nat]: ToInt[N] =
inline implicit def materialize[N <: Int]: ToInt[N] =
new ToInt[N] { override def apply(): Int = toInt[N] }

private inline def toInt[N <: Nat]: Int =
private inline def toInt[N <: Int]: Int =
inline erasedValue[N] match {
case _: _0 => 0
case _: Succ[n] => toInt[n] + 1
case _: 0 => 0
case _: S[n] => toInt[n] + 1
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package eu.timepit.refined.internal

import scala.compiletime.{constValue, error}
import shapeless.{Nat, Witness}

/**
* `WitnessAs[A, B]` provides the singleton value of type `A` in `fst`
Expand All @@ -28,8 +27,8 @@ final case class WitnessAs[A, B](fst: A, snd: B)
object WitnessAs extends WitnessAs1 {
def apply[A, B](implicit ev: WitnessAs[A, B]): WitnessAs[A, B] = ev

implicit def natWitnessAs[B, A <: Nat](implicit
wa: Witness.Aux[A],
implicit def intWitnessAs[B, A <: Int](implicit
wa: ValueOf[A],
ta: ToInt[A],
nb: Numeric[B]
): WitnessAs[A, B] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import eu.timepit.refined.boolean.{And, Not}
import eu.timepit.refined.internal.ToInt
import eu.timepit.refined.internal.WitnessAs
import eu.timepit.refined.numeric._
import shapeless.Nat
import shapeless.nat.{_0, _2}

/**
* Module for numeric predicates.
Expand Down Expand Up @@ -50,25 +48,25 @@ object numeric extends NumericInference {
type GreaterEqual[N] = Not[Less[N]]

/** Predicate that checks if a numeric value is positive (> 0). */
type Positive = Greater[_0]
type Positive = Greater[0]

/** Predicate that checks if a numeric value is zero or negative (<= 0). */
type NonPositive = Not[Positive]

/** Predicate that checks if a numeric value is negative (< 0). */
type Negative = Less[_0]
type Negative = Less[0]

/** Predicate that checks if a numeric value is zero or positive (>= 0). */
type NonNegative = Not[Negative]

/** Predicate that checks if an integral value is evenly divisible by `N`. */
type Divisible[N] = Modulo[N, _0]
type Divisible[N] = Modulo[N, 0]

/** Predicate that checks if an integral value is not evenly divisible by `N`. */
type NonDivisible[N] = Not[Divisible[N]]

/** Predicate that checks if an integral value is evenly divisible by 2. */
type Even = Divisible[_2]
type Even = Divisible[2]

/** Predicate that checks if an integral value is not evenly divisible by 2. */
type Odd = Not[Even]
Expand Down Expand Up @@ -135,11 +133,11 @@ private[refined] trait NumericInference {
): Less[A] ==> Less[B] =
Inference(nc.lt(wa.snd, wb.snd), s"lessInference(${wa.snd}, ${wb.snd})")

implicit def lessInferenceNat[A <: Nat, B <: Nat](implicit
implicit def lessInferenceInt[A <: Int, B <: Int](implicit
ta: ToInt[A],
tb: ToInt[B]
): Less[A] ==> Less[B] =
Inference(ta() < tb(), s"lessInferenceNat(${ta()}, ${tb()})")
Inference(ta() < tb(), s"lessInferenceInt(${ta()}, ${tb()})")

implicit def greaterInference[C, A, B](implicit
wa: WitnessAs[A, C],
Expand All @@ -148,11 +146,11 @@ private[refined] trait NumericInference {
): Greater[A] ==> Greater[B] =
Inference(nc.gt(wa.snd, wb.snd), s"greaterInference(${wa.snd}, ${wb.snd})")

implicit def greaterInferenceNat[A <: Nat, B <: Nat](implicit
implicit def greaterInferenceNat[A <: Int, B <: Int](implicit
ta: ToInt[A],
tb: ToInt[B]
): Greater[A] ==> Greater[B] =
Inference(ta() > tb(), s"greaterInferenceNat(${ta()}, ${tb()})")
Inference(ta() > tb(), s"greaterInferenceInt(${ta()}, ${tb()})")

implicit def greaterEqualInference[A]: Greater[A] ==> GreaterEqual[A] =
Inference.alwaysValid("greaterEqualInference")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package eu.timepit

import eu.timepit.refined.api.{Refined, RefType}
import eu.timepit.refined.internal._
import shapeless.tag.@@

package object refined {

Expand All @@ -13,12 +12,4 @@ package object refined {
* Note: `V` stands for '''v'''alue class.
*/
def refineV[P]: RefinePartiallyApplied[Refined, P] = RefType.refinedRefType.refine[P]

/**
* Alias for `[[api.RefType.refine]][P]` with `shapeless.tag.@@` as type
* parameter for `[[api.RefType]]`.
*
* Note: `T` stands for '''t'''ag.
*/
def refineT[P]: RefinePartiallyApplied[@@, P] = RefType.tagRefType.refine[P]
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import eu.timepit.refined.api.{Refined, RefinedType, RefinedTypeOps}
import eu.timepit.refined.collection.{MaxSize, NonEmpty, Size}
import eu.timepit.refined.numeric.Interval
import eu.timepit.refined.string.{HexStringSpec, Trimmed}
import shapeless.Nat._1

/** Module for `String` refined types. */
object string {
Expand Down Expand Up @@ -59,7 +58,7 @@ object string {
object NonEmptyString extends RefinedTypeOps[NonEmptyString, String]

/** A `String` that is not empty with length less than or equal to `N`. */
type NonEmptyFiniteString[N] = String Refined Size[Interval.Closed[_1, N]]
type NonEmptyFiniteString[N] = String Refined Size[Interval.Closed[1, N]]

object NonEmptyFiniteString {
class NonEmptyFiniteStringOps[N <: Int](implicit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ class RefTypeConfigConvertSpec extends Properties("RefTypeConfigConvert") {

// scala 3 macro provide type representation in this way
val expected3 = expectedFailure(
"eu.timepit.refined.api.Refined[scala.Int, eu.timepit.refined.numeric.Greater[shapeless.nat._0]]"
"eu.timepit.refined.api.Refined[scala.Int, eu.timepit.refined.numeric.Greater[0]]"
)
val expected4 = expectedFailure(
s"eu.timepit.refined.api.Refined$$package.Refined[scala.Int, eu.timepit.refined.numeric.Greater[shapeless.nat._0]]"
s"eu.timepit.refined.api.Refined$$package.Refined[scala.Int, eu.timepit.refined.numeric.Greater[0]]"
)

val actual = loadConfigWithValue("0")
Expand Down

0 comments on commit e2a1640

Please sign in to comment.