-
Notifications
You must be signed in to change notification settings - Fork 1
/
Encoder.scala
98 lines (74 loc) · 3.76 KB
/
Encoder.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package mess.codec
import java.time.Instant
import mess.Fmt
import scala.annotation.tailrec
import scala.collection.mutable
trait Encoder[A] extends Serializable { self =>
def apply(a: A): Fmt
final def contramap[B](f: B => A): Encoder[B] = a => self(f(a))
final def map(f: Fmt => Fmt): Encoder[A] = a => f(self(a))
}
object Encoder extends Encoder1 with TupleEncoder {
trait AsArray[A] extends Encoder[A] {
def applyToArray(a: A): Fmt.MArray
final def apply(a: A): Fmt = applyToArray(a)
final def mapArray(f: Fmt.MArray => Fmt.MArray): AsArray[A] = a => f(applyToArray(a))
}
trait AsMap[A] extends Encoder[A] {
def applyToMap(a: A): Fmt.MMap
final def apply(a: A): Fmt = applyToMap(a)
final def mapMap(f: Fmt.MMap => Fmt.MMap): AsMap[A] = a => f(applyToMap(a))
}
object AsMap extends MirrorEncoder
def apply[A](implicit A: Encoder[A]): Encoder[A] = A
def asMap[A](implicit A: Encoder.AsMap[A]): Encoder.AsMap[A] = A
def asArray[A](implicit A: Encoder.AsArray[A]): Encoder.AsArray[A] = A
final def instance[A](fa: A => Fmt): Encoder[A] = fa(_)
}
private[codec] trait Encoder1 {
implicit final val encodeFmt: Encoder[Fmt] = identity(_)
implicit final val encodeBoolean: Encoder[Boolean] = Fmt.fromBoolean(_)
implicit final val encodeBytes: Encoder[Array[Byte]] = Fmt.fromBytes(_)
implicit final val encodeByte: Encoder[Byte] = Fmt.fromByte(_)
implicit final val encodeShort: Encoder[Short] = Fmt.fromShort(_)
implicit final val encodeInt: Encoder[Int] = Fmt.fromInt(_)
implicit final val encodeLong: Encoder[Long] = Fmt.fromLong(_)
implicit final val encodeBigInt: Encoder[BigInt] = Fmt.fromBigInt(_)
implicit final val encodeDouble: Encoder[Double] = Fmt.fromDouble(_)
implicit final val encodeFloat: Encoder[Float] = Fmt.fromFloat(_)
implicit final val encodeChar: Encoder[Char] = a => Fmt.fromString(a.toString)
implicit final val encodeString: Encoder[String] = Fmt.fromString(_)
implicit final val encodeTimestamp: Encoder[Instant] = Fmt.fromInstant(_)
implicit final def encodeSymbol[K <: Symbol]: Encoder[K] = a => Fmt.fromString(a.name)
implicit final def encodeOption[A](implicit A: Encoder[A]): Encoder[Option[A]] = {
case Some(v) => A(v)
case None => Fmt.nil
}
implicit final def encodeSome[A](implicit A: Encoder[A]): Encoder[Some[A]] =
A.contramap[Some[A]](_.get)
implicit final val encodeNone: Encoder[None.type] = _ => Fmt.nil
@tailrec private def buildVector[A](rem: Iterator[A], acc: mutable.Builder[Fmt, Vector[Fmt]])(implicit
A: Encoder[A]
): Vector[Fmt] =
if (!rem.hasNext) acc.result()
else buildVector(rem, acc += A(rem.next()))
implicit final def encodeSeq[A: Encoder]: Encoder.AsArray[Seq[A]] =
a => Fmt.MArray(buildVector(a.iterator, Vector.newBuilder))
implicit final def encodeSet[A: Encoder]: Encoder.AsArray[Set[A]] =
a => Fmt.MArray(buildVector(a.iterator, Vector.newBuilder))
implicit final def encodeList[A: Encoder]: Encoder.AsArray[List[A]] =
a => Fmt.MArray(buildVector(a.iterator, Vector.newBuilder))
implicit final def encodeVector[A: Encoder]: Encoder.AsArray[Vector[A]] =
a => Fmt.MArray(buildVector(a.iterator, Vector.newBuilder))
@tailrec private def buildMap[K, V](it: Iterator[(K, V)], acc: mutable.Builder[(Fmt, Fmt), Map[Fmt, Fmt]])(implicit
encodeK: Encoder[K],
encodeV: Encoder[V]
): Map[Fmt, Fmt] =
if (!it.hasNext) acc.result()
else {
val (k, v) = it.next()
buildMap(it, acc += encodeK(k) -> encodeV(v))
}
implicit final def encodeMapAsMaps[K: Encoder, V: Encoder]: Encoder.AsMap[Map[K, V]] =
a => Fmt.MMap(buildMap(a.iterator, Map.newBuilder))
}