-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Mirror.scala
61 lines (48 loc) · 2.15 KB
/
Mirror.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package scala.deriving
/** Mirrors allows typelevel access to enums, case classes and objects, and their sealed parents.
*/
sealed trait Mirror {
/** The mirrored *-type */
type MirroredMonoType
/** The name of the type */
type MirroredLabel <: String
/** The names of the product elements */
type MirroredElemLabels <: Tuple
}
object Mirror {
/** The Mirror for a sum type */
trait Sum extends Mirror { self =>
/** The ordinal number of the case class of `x`. For enums, `ordinal(x) == x.ordinal` */
def ordinal(x: MirroredMonoType): Int
}
/** The Mirror for a product type */
trait Product extends Mirror {
/** Create a new instance of type `T` with elements taken from product `p`. */
def fromProduct(p: scala.Product): MirroredMonoType
}
trait Singleton extends Product {
type MirroredMonoType = this.type
type MirroredType = this.type
type MirroredElemTypes = EmptyTuple
type MirroredElemLabels = EmptyTuple
def fromProduct(p: scala.Product): MirroredMonoType = this
}
/** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */
class SingletonProxy(val value: AnyRef) extends Product {
type MirroredMonoType = value.type
type MirroredType = value.type
type MirroredElemTypes = EmptyTuple
type MirroredElemLabels = EmptyTuple
def fromProduct(p: scala.Product): MirroredMonoType = value
}
type Of[T] = Mirror { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple }
type ProductOf[T] = Mirror.Product { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple }
type SumOf[T] = Mirror.Sum { type MirroredType = T; type MirroredMonoType = T; type MirroredElemTypes <: Tuple }
extension [T](p: ProductOf[T])
/** Create a new instance of type `T` with elements taken from product `a`. */
def fromProductTyped[A <: scala.Product, Elems <: p.MirroredElemTypes](a: A)(using m: ProductOf[A] { type MirroredElemTypes = Elems }): T =
p.fromProduct(a)
/** Create a new instance of type `T` with elements taken from tuple `t`. */
def fromTuple(t: p.MirroredElemTypes): T =
p.fromProduct(t)
}