/
YamlError.scala
99 lines (85 loc) · 3.48 KB
/
YamlError.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
package org.virtuslab.yaml
import scala.reflect.ClassTag
import scala.util.control.NoStackTrace
import org.virtuslab.yaml.internal.load.reader.token.Token
import org.virtuslab.yaml.internal.load.reader.token.TokenKind
import org.virtuslab.yaml.internal.load.TagValue
/**
* An ADT representing a decoding failure.
*/
sealed trait YamlError {
def msg: String
}
sealed trait ParseError extends YamlError
object ParseError {
def from(expected: String, got: Token): ParseError = ExpectedTokenKind(expected, got)
def from(expected: TokenKind, got: Token): ParseError = ParseError.from(expected.toString, got)
final case class ExpectedTokenKind(expected: String, got: Token) extends ParseError {
def msg: String =
s"""|Expected
|$expected but instead got ${got.kind}
|${got.range.errorMsg}""".stripMargin
}
final case class NoRegisteredTagDirective(handleKey: String, tokenTag: Token) extends ParseError {
def msg: String = s"There is no registered tag directive for handle $handleKey"
}
}
final case class ComposerError(msg: String) extends YamlError
final case class ModifyError(msg: String) extends YamlError
final case class ConstructError(
errorMsg: String,
node: Option[Node],
expected: Option[String]
) extends YamlError {
def msg: String = node.flatMap(_.pos) match {
case Some(range) =>
s"""|$errorMsg
|at ${range.start.line}:${range.start.column},${expected
.map(exp => s" expected $exp")
.getOrElse("")}
|${range.errorMsg} """.stripMargin
case None =>
errorMsg
}
}
object ConstructError {
private def from(
errorMsg: String,
node: Option[Node],
expected: Option[String]
): ConstructError = ConstructError(errorMsg, node, expected)
def from(errorMsg: String, node: Node, expected: String): ConstructError =
from(errorMsg, Some(node), Some(expected))
def from(errorMsg: String, expected: String, node: Node): ConstructError =
from(errorMsg, Some(node), Some(expected))
def from(errorMsg: String, node: Node): ConstructError = from(errorMsg, Some(node), None)
def from(errorMsg: String, expected: String): ConstructError =
from(errorMsg, None, Some(expected))
def from(errorMsg: String): ConstructError = from(errorMsg, None, None)
def from(t: Throwable, node: Node, expected: String): ConstructError =
from(t.getMessage, Some(node), Some(expected))
def from(t: Throwable, expected: String, node: Node): ConstructError =
from(t.getMessage, Some(node), Some(expected))
def from(t: Throwable, node: Node): ConstructError = from(t.getMessage, Some(node), None)
def from(t: Throwable, expected: String): ConstructError =
from(t.getMessage, None, Some(expected))
def from(t: Throwable): ConstructError = from(t.getMessage, None, None)
}
sealed trait ScannerError extends Throwable with YamlError with NoStackTrace
object ScannerError {
def from(obtained: String, got: Token): ScannerError = Obtained(obtained, got)
def from(range: Range, msg: String): ScannerError = AtRange(range, msg)
case class Obtained(obtained: String, got: Token) extends ScannerError {
def msg: String =
s"""|Obtained
|$obtained but expected got ${got.kind}
|${got.range.errorMsg}""".stripMargin
}
case class AtRange(range: Range, rawMsg: String) extends ScannerError {
def msg: String =
s"""|Error at line ${range.start.line}, column ${range.start.column}:
|${range.errorMsg}
|$msg
|""".stripMargin
}
}