1+ import scala .deriving ._
2+ import scala .compiletime .erasedValue
3+
4+ trait JsonEncoder [T ] {
5+ def encode (elem : T ): String
6+ }
7+
8+ object JsonEncoder {
9+ import scala .compiletime .{erasedValue , summonFrom }
10+ import compiletime ._
11+ import scala .deriving ._
12+
13+ inline def encodeElem [T ](elem : T ): String = summonFrom {
14+ case encoder : JsonEncoder [T ] => encoder.encode(elem)
15+ }
16+
17+ inline def encodeElems [Elems <: Tuple ](idx : Int )(value : Any ): List [String ] =
18+ inline erasedValue[Elems ] match {
19+ case _ : (elem *: elems1) =>
20+ encodeElem[elem](productElement[elem](value, idx)) :: encodeElems[elems1](idx + 1 )(value)
21+ case _ => Nil
22+ }
23+
24+ inline def derived [T ](implicit ev : Mirror .Of [T ]): JsonEncoder [T ] = new JsonEncoder [T ] {
25+ def encode (value : T ): String =
26+ inline ev match {
27+ case m : Mirror .SumOf [T ] =>
28+ " not supporting this case yet"
29+ case m : Mirror .ProductOf [T ] =>
30+ val elems = encodeElems[m.MirroredElemTypes ](0 )(value)
31+ val labels = value.asInstanceOf [Product ].productElementNames
32+ val keyValues = labels.zip(elems).map((k, v) => s " $k: $v" )
33+ " {" + (keyValues).mkString(" , " ) + " }"
34+ case other =>
35+ throw new RuntimeException (" mirror was an invalid value: " + other)
36+ }
37+ }
38+
39+ given listEncoder [T ]: (encoder : JsonEncoder [T ]) => JsonEncoder [List [T ]] {
40+ def encode (list : List [T ]) = s " [ ${ list.map(v => encoder.encode(v)).mkString(" , " ) }] "
41+ }
42+
43+ given intEncoder : JsonEncoder [Int ] {
44+ def encode (value : Int ) = value + " "
45+ }
46+
47+ given stringEncoder : JsonEncoder [String ] {
48+ def encode (value : String ) = value
49+ }
50+ }
0 commit comments