Mirror Annotations & Default Extraction — a Scala 3 macro library that extends scala.deriving.Mirror with
annotation metadata, default values, generated members, and transparent wrapper support.
Scala 3's built-in Mirror provides basic type-level information about case classes and enums, but it stops short of
exposing annotations, default values, or computed members. M&DE fills that gap — it derives enriched mirrors at
compile time that carry:
- Type-level annotation metadata — custom annotations on types and fields, queryable at both type level and runtime
- Default value extraction — from constructor defaults,
@whenAbsentannotations, and@optionalParammarkers - Generated members —
@generatedvals and defs exposed as first-class elements of the mirror - Transparent wrappers —
@transparentsingle-field case classes with compile-time wrap/unwrap - Custom labels —
@nameto override the label of a type or field
Made supports case classes, enums, sealed traits, objects, value classes, and higher-kinded types.
M&DE is published to Maven Central under io.github.halotukozak. Requires Scala 3.
//> using scala 3.8.4-RC2
//> using dep io.github.halotukozak::made::0.1.0scalaVersion := "3.8.4-RC2"
libraryDependencies += "io.github.halotukozak" %% "made" % "0.1.0"def scalaVersion = "3.8.4-RC2"
def mvDeps = Seq(mvn"io.github.halotukozak::made::0.1.0")Derive a Made mirror for a case class and inspect its fields, labels, and annotations.
import made.*
import made.annotation.*
case class User(@name("user_name") name: String, age: Int = 18)
val mirror = Made.derived[User]
// Type-level
// mirror.Label =:= "User"
// mirror.ElemLabels =:= ("user_name", "age")
// mirror.ElemTypes =:= (String, Int)
// Runtime
val (nameElem, ageElem) = mirror.elems
nameElem.label // "user_name"
ageElem.default // Some(18)
// Build values
val u = mirror.fromUnsafeArray(Array("Alice", 30))See the guides for full coverage of deriving type classes, default extraction, generated members, and transparent wrapping.
M&DE is inspired by: