-
Notifications
You must be signed in to change notification settings - Fork 25
/
problem.scala
65 lines (49 loc) · 1.53 KB
/
problem.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
// Copyright (c) 2016-2020 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause
package edu.gemini.grackle
import io.circe._
import io.circe.syntax._
/** A problem, to be reported back to the user. */
final case class Problem(
message: String,
locations: List[(Int, Int)] = Nil,
path: List[String] = Nil
) {
override def toString = {
lazy val pathText: String =
path.mkString("/")
lazy val locationsText: String =
locations.map { case (a, b) =>
if (a == b) a.toString else s"$a..$b"
} .mkString(", ")
(path.nonEmpty, locations.nonEmpty) match {
case (true, true) => s"$message (at $pathText: $locationsText)"
case (true, false) => s"$message (at $pathText)"
case (false, true) => s"$message (at $locationsText)"
case (false, false) => message
}
}
}
object Problem {
implicit val ProblemEncoder: Encoder[Problem] = { p =>
val locationsField: List[(String, Json)] =
if (p.locations.isEmpty) Nil
else List(
"locations" ->
p.locations.map { case (line, col) =>
Json.obj(
"line" -> line.asJson,
"col" -> col.asJson
)
} .asJson
)
val pathField: List[(String, Json)] =
if (p.path.isEmpty) Nil
else List(("path" -> p.path.asJson))
Json.fromFields(
"message" -> p.message.asJson ::
locationsField :::
pathField
)
}
}