Skip to content

Commit

Permalink
Some progress on exception avoidance
Browse files Browse the repository at this point in the history
  • Loading branch information
propensive committed Jul 6, 2023
1 parent 762ffd6 commit 5c15f65
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
22 changes: 11 additions & 11 deletions src/core/schema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,17 @@ object JsonValidationError:
case PatternMismatch(value, pattern) =>
msg"the value did not conform to the regular expression ${pattern.pattern}"

case class JsonValidationError(issue: JsonValidationError.Issue)
import JsonValidationError.Issue, Issue.*

case class JsonValidationError(issue: Issue)
extends Error(msg"the JSON was not valid according to the schema")

trait JsonValueAccessor[NameType <: Label, ValueType]
extends ValueAccessor[JsonRecord, Maybe[Json], NameType, ValueType]:
def access(value: Json): ValueType

def transform(value: Maybe[Json], params: List[String]): ValueType =
value.mm(access(_)).or(throw JsonValidationError(JsonValidationError.Issue.MissingValue))
value.mm(access(_)).or(throw JsonValidationError(MissingValue))

object JsonRecord:

Expand Down Expand Up @@ -130,28 +132,26 @@ object JsonRecord:
(value, params) => value.mm(_.as[Text])

given pattern
: ValueAccessor[JsonRecord, Maybe[Json], "pattern", Text throws JsonValidationError] with
def transform(value: Maybe[Json], params: List[String]): Text throws JsonValidationError =
: ValueAccessor[JsonRecord, Maybe[Json], "pattern", Text] with
def transform(value: Maybe[Json], params: List[String]): Text =
value.mm: value =>
(params: @unchecked) match
case List(pattern: String) =>
val regex = Regex(Text(pattern))
if regex.matches(value.as[Text]) then value.as[Text]
else throw JsonValidationError(JsonValidationError.Issue.PatternMismatch(value.as[Text],
regex))
.or(throw JsonValidationError(JsonValidationError.Issue.MissingValue))
else throw JsonValidationError(PatternMismatch(value.as[Text], regex))
.or(throw JsonValidationError(MissingValue))

given maybePattern: ValueAccessor[JsonRecord, Maybe[Json], "pattern?", Maybe[Text] throws
JsonValidationError] with
given maybePattern: ValueAccessor[JsonRecord, Maybe[Json], "pattern?", Maybe[Text]] with
def transform
(value: Maybe[Json], params: List[String] = Nil)
: Maybe[Text] throws JsonValidationError =
: Maybe[Text] =
value.mm: value =>
(params: @unchecked) match
case pattern :: Nil =>
val regex = Regex(Text(pattern))
if regex.matches(value.as[Text]) then value.as[Text]
else throw JsonValidationError(JsonValidationError.Issue.PatternMismatch(value.as[Text], regex))
else throw JsonValidationError(PatternMismatch(value.as[Text], regex))

given maybeInteger: ValueAccessor[JsonRecord, Maybe[Json], "integer?", Maybe[Int]] =
(value, params) => value.mm(_.as[Int])
Expand Down
2 changes: 1 addition & 1 deletion src/test/example.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ object ExampleSchema extends JsonSchema(unsafely(Json.parse(t"""{
"items": {
"height": { "type": "integer", "description": "Height", "minimum": 1, "maximum": 99 },
"weight": { "type": "number", "description": "Weight" },
"color": { "type": "string", "description": "Colour" }
"color": { "type": "string", "description": "Colour", "pattern": "#[0-9a-f]{6}" }
}
}
}
Expand Down
18 changes: 12 additions & 6 deletions src/test/tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ object Tests extends Suite(t"Villainy tests"):
t"""{
"name": "Jim",
"sub": { "date": "11/12/20" },
"children": [{"height": 100, "weight": 0.8, "color": "green" },
{"height": 9, "weight": 30.0, "color": "red"}],
"children": [
{"height": 100, "weight": 0.8, "color": "green" },
{"height": 9, "weight": 30.0, "color": "#ff0000"}
],
"pattern": "a.b",
"domain": "example.com"
}"""
Expand Down Expand Up @@ -66,9 +68,13 @@ object Tests extends Suite(t"Villainy tests"):
record.children.head.weight
.assert(_ == 0.8)

test(t"Get a nested item value"):
record.children.head.color
.assert(_ == t"green")
test(t"A bad pattern-checked value throws an exceptions"):
unsafely(capture[JsonValidationError, Maybe[Text]](record.children.head.color))
.assert(_ == JsonValidationError(JsonValidationError.Issue.PatternMismatch(t"green", r"#[0-9a-f]{6}")))

test(t"A bad pattern-checked value throws an exceptions"):
unsafely(record.children(1).color)
.assert(_ == t"#ff0000")

test(t"Get a nested item value"):
record.sub.date
Expand All @@ -78,7 +84,7 @@ object Tests extends Suite(t"Villainy tests"):
unsafely:
record.pattern
.assert(_ == unsafely(Regex(t"a.b")))

test(t"Get some values in a list"):
unsafely:
capture:
Expand Down

0 comments on commit 5c15f65

Please sign in to comment.