-
Notifications
You must be signed in to change notification settings - Fork 3
/
Decoder.scala
98 lines (91 loc) · 3.21 KB
/
Decoder.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
/*
* Copyright 2022 Hossein Naderi
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.hnaderi.k8s.utils
abstract class Decoder[+R] { self =>
def apply[T: Reader](t: T): Either[String, R]
final def map[RR](f: R => RR): Decoder[RR] = new Decoder[RR] {
def apply[T: Reader](t: T): Either[String, RR] = self(t).map(f)
}
final def emap[RR](f: R => Either[String, RR]): Decoder[RR] =
new Decoder[RR] {
def apply[T: Reader](t: T): Either[String, RR] = self(t).flatMap(f)
}
final def orElse[RR >: R](dec: Decoder[RR]): Decoder[RR] =
new Decoder[RR] {
def apply[T: Reader](t: T): Either[String, RR] = {
self(t) match {
case Right(value) => Right(value)
case _ => dec(t)
}
}
}
}
object Decoder {
def apply[R](implicit d: Decoder[R]): Decoder[R] = d
implicit lazy val intDecoder: Decoder[Int] =
new Decoder[Int] {
def apply[T](t: T)(implicit r: Reader[T]): Either[String, Int] = r.int(t)
}
implicit lazy val longDecoder: Decoder[Long] =
new Decoder[Long] {
def apply[T](t: T)(implicit r: Reader[T]): Either[String, Long] =
r.long(t)
}
implicit lazy val doubleDecoder: Decoder[Double] =
new Decoder[Double] {
def apply[T](t: T)(implicit r: Reader[T]): Either[String, Double] =
r.double(t)
}
implicit lazy val stringDecoder: Decoder[String] =
new Decoder[String] {
def apply[T](t: T)(implicit r: Reader[T]): Either[String, String] =
r.string(t)
}
implicit lazy val booleanDecoder: Decoder[Boolean] =
new Decoder[Boolean] {
def apply[T](t: T)(implicit r: Reader[T]): Either[String, Boolean] =
r.bool(t)
}
implicit def arrDecoder[A](implicit dec: Decoder[A]): Decoder[Seq[A]] =
new Decoder[Seq[A]] {
def apply[T](t: T)(implicit r: Reader[T]): Either[String, Seq[A]] = {
r.array(t)
.flatMap(_.foldLeft[Either[String, List[A]]](Right(Nil)) {
case (el, a) => el.flatMap(l => dec(a).map(l :+ _))
})
}
}
implicit def mapDecoder[A](implicit
dec: Decoder[A]
): Decoder[Map[String, A]] =
new Decoder[Map[String, A]] {
def apply[T](
t: T
)(implicit r: Reader[T]): Either[String, Map[String, A]] =
r.obj(t)
.flatMap(
_.foldLeft[Either[String, List[(String, A)]]](Right(Nil)) {
case (el, (k, a)) => el.flatMap(l => dec(a).map((k, _) :: l))
}.map(_.toMap)
)
}
def const[R](r: R): Decoder[R] = new Decoder[R] {
def apply[T: Reader](t: T): Either[String, R] = Right(r)
}
def failed[R](msg: String): Decoder[R] = new Decoder[R] {
def apply[T: Reader](t: T): Either[String, R] = Left(msg)
}
}