-
Notifications
You must be signed in to change notification settings - Fork 158
/
boolean.scala
90 lines (70 loc) · 3.04 KB
/
boolean.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
package eu.timepit.refined
import shapeless.{ ::, HList, HNil }
object boolean {
/** Constant predicate that is always true. */
trait True
/** Constant predicate that is always false. */
trait False
/** Negation of the predicate `P`. */
trait Not[P]
/** Conjunction of the predicates `A` and `B`. */
trait And[A, B]
/** Disjunction of the predicates `A` and `B`. */
trait Or[A, B]
/** Conjunction of all predicates in `PS`. */
trait AllOf[PS]
/** Disjunction of all predicates in `PS`. */
trait AnyOf[PS]
implicit def truePredicate[T]: Predicate[True, T] =
Predicate.alwaysTrue
implicit def falsePredicate[T]: Predicate[False, T] =
Predicate.alwaysFalse
implicit def notPredicate[P, T](implicit p: Predicate[P, T]): Predicate[Not[P], T] =
new Predicate[Not[P], T] {
def isValid(t: T): Boolean = !p.isValid(t)
def show(t: T): String = s"!${p.show(t)}"
override def validated(t: T): Option[String] =
p.validated(t) match {
case Some(_) => None
case None => Some(s"Predicate ${p.show(t)} did not fail.")
}
}
implicit def andPredicate[A, B, T](implicit pa: Predicate[A, T], pb: Predicate[B, T]): Predicate[A And B, T] =
new Predicate[A And B, T] {
def isValid(t: T): Boolean = pa.isValid(t) && pb.isValid(t)
def show(t: T): String = s"(${pa.show(t)} && ${pb.show(t)})"
override def validated(t: T): Option[String] =
(pa.validated(t), pb.validated(t)) match {
case (Some(sl), Some(sr)) =>
Some(s"Both predicates of ${show(t)} failed. Left: $sl Right: $sr")
case (Some(sl), None) =>
Some(s"Left predicate of ${show(t)} failed: $sl")
case (None, Some(sr)) =>
Some(s"Right predicate of ${show(t)} failed: $sr")
case _ => None
}
}
implicit def orPredicate[A, B, T](implicit pa: Predicate[A, T], pb: Predicate[B, T]): Predicate[A Or B, T] =
new Predicate[A Or B, T] {
def isValid(t: T): Boolean = pa.isValid(t) || pb.isValid(t)
def show(t: T): String = s"(${pa.show(t)} || ${pb.show(t)})"
override def validated(t: T): Option[String] =
(pa.validated(t), pb.validated(t)) match {
case (Some(sl), Some(sr)) =>
Some(s"Both predicates of ${show(t)} failed. Left: $sl Right: $sr")
case _ => None
}
}
implicit def allOfHNilPredicate[T]: Predicate[AllOf[HNil], T] =
Predicate.alwaysTrue
implicit def allOfHConsPredicate[PH, PT <: HList, T](implicit ph: Predicate[PH, T], pt: Predicate[AllOf[PT], T]): Predicate[AllOf[PH :: PT], T] =
Predicate.instance(
t => ph.isValid(t) && pt.isValid(t),
t => s"(${ph.show(t)} && ${pt.show(t)})")
implicit def anyOfHNilPredicate[T]: Predicate[AnyOf[HNil], T] =
Predicate.alwaysFalse
implicit def anyOfHConsPredicate[PH, PT <: HList, T](implicit ph: Predicate[PH, T], pt: Predicate[AnyOf[PT], T]): Predicate[AnyOf[PH :: PT], T] =
Predicate.instance(
t => ph.isValid(t) || pt.isValid(t),
t => s"(${ph.show(t)} || ${pt.show(t)})")
}