-
Notifications
You must be signed in to change notification settings - Fork 15
/
ConfigImplTyped.scala
133 lines (120 loc) · 4.94 KB
/
ConfigImplTyped.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package parsley.token.errors
import parsley.Parsley, Parsley.pure
import parsley.errors.combinator, combinator.ErrorMethods
import parsley.position
trait FilterOps[A] {
private [parsley] def filter(p: Parsley[A])(f: A => Boolean): Parsley[A]
private [parsley] def collect[B](p: Parsley[A])(f: PartialFunction[A, B]): Parsley[B] = this.filter(p)(f.isDefinedAt).map(f)
private [parsley] def injectLeft[B]: FilterOps[Either[A, B]]
private [parsley] def injectRight[B]: FilterOps[Either[B, A]]
}
private [parsley] object FilterOps {
def amendThenDislodge[A](full: Boolean)(p: Parsley[A]): Parsley[A] = {
if (full) combinator.amendThenDislodge(p)
else p
}
}
trait FilterConfig[A] extends FilterOps[A]
trait SpecialisedFilterConfig[A] extends FilterConfig[A]
trait VanillaFilterConfig[A] extends FilterConfig[A]
abstract class SpecialisedMessage[A](fullAmend: Boolean) extends SpecialisedFilterConfig[A] { self =>
def message(x: A): Seq[String]
private [parsley] final override def filter(p: Parsley[A])(f: A => Boolean) = FilterOps.amendThenDislodge(fullAmend) {
p.guardAgainst {
case x if !f(x) => message(x)
}
}
private [parsley] final override def collect[B](p: Parsley[A])(f: PartialFunction[A, B]) = FilterOps.amendThenDislodge(fullAmend) {
p.collectMsg(message(_))(f)
}
private [parsley] final override def injectLeft[B] = new SpecialisedMessage[Either[A, B]](fullAmend) {
def message(xy: Either[A, B]) = {
val Left(x) = xy
self.message(x)
}
}
private [parsley] final override def injectRight[B] = new SpecialisedMessage[Either[B, A]](fullAmend) {
def message(xy: Either[B, A]) = {
val Right(y) = xy
self.message(y)
}
}
}
abstract class Unexpected[A](fullAmend: Boolean) extends VanillaFilterConfig[A] { self =>
def unexpected(x: A): String
private [parsley] final override def filter(p: Parsley[A])(f: A => Boolean) = FilterOps.amendThenDislodge(fullAmend) {
p.unexpectedWhen {
case x if !f(x) => unexpected(x)
}
}
private [parsley] final override def injectLeft[B] = new Unexpected[Either[A, B]](fullAmend) {
def unexpected(xy: Either[A, B]) = {
val Left(x) = xy
self.unexpected(x)
}
}
private [parsley] final override def injectRight[B] = new Unexpected[Either[B, A]](fullAmend) {
def unexpected(xy: Either[B, A]) = {
val Right(y) = xy
self.unexpected(y)
}
}
}
abstract class Because[A](fullAmend: Boolean) extends VanillaFilterConfig[A] { self =>
def reason(x: A): String
private [parsley] final override def filter(p: Parsley[A])(f: A => Boolean) = FilterOps.amendThenDislodge(fullAmend) {
p.filterOut {
case x if !f(x) => reason(x)
}
}
private [parsley] final override def injectLeft[B] = new Because[Either[A, B]](fullAmend) {
def reason(xy: Either[A, B]) = {
val Left(x) = xy
self.reason(x)
}
}
private [parsley] final override def injectRight[B] = new Because[Either[B, A]](fullAmend) {
def reason(xy: Either[B, A]) = {
val Right(y) = xy
self.reason(y)
}
}
}
abstract class UnexpectedBecause[A](fullAmend: Boolean) extends VanillaFilterConfig[A] { self =>
def unexpected(x: A): String
def reason(x: A): String
private [parsley] final override def filter(p: Parsley[A])(f: A => Boolean) = FilterOps.amendThenDislodge(fullAmend) {
combinator.amendThenDislodge {
position.internalOffsetSpan(combinator.entrench(p)).flatMap { case (os, x, oe) =>
if (f(x)) combinator.unexpected(oe - os, this.unexpected(x)).explain(reason(x))
else pure(x)
}
}
}
private [parsley] final override def injectLeft[B] = new UnexpectedBecause[Either[A, B]](fullAmend) {
def unexpected(xy: Either[A, B]) = {
val Left(x) = xy
self.unexpected(x)
}
def reason(xy: Either[A, B]) = {
val Left(x) = xy
self.reason(x)
}
}
private [parsley] final override def injectRight[B] = new UnexpectedBecause[Either[B, A]](fullAmend) {
def unexpected(xy: Either[B, A]) = {
val Right(y) = xy
self.unexpected(y)
}
def reason(xy: Either[B, A]) = {
val Right(x) = xy
self.reason(x)
}
}
}
final class BasicFilter[A] extends SpecialisedFilterConfig[A] with VanillaFilterConfig[A] {
private [parsley] final override def filter(p: Parsley[A])(f: A => Boolean) = p.filter(f)
private [parsley] final override def collect[B](p: Parsley[A])(f: PartialFunction[A, B]) = p.collect(f)
private [parsley] final override def injectLeft[B] = new BasicFilter[Either[A, B]]
private [parsley] final override def injectRight[B] = new BasicFilter[Either[B, A]]
}