Skip to content

Commit

Permalink
Merge pull request #323 from VirtusLab/issue-120
Browse files Browse the repository at this point in the history
fix conversion of !!null to non-optional types
  • Loading branch information
lbialy authored Jul 21, 2024
2 parents a3aa5b9 + c4ef564 commit a58465a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
25 changes: 18 additions & 7 deletions core/shared/src/main/scala/org/virtuslab/yaml/YamlDecoder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,19 @@ object YamlDecoder extends YamlDecoderCompanionCrossCompat {
override def construct(
node: Node
)(implicit settings: LoadSettings = LoadSettings.empty): Either[ConstructError, T] =
if (pf.isDefinedAt(node)) pf(node)
if (node.tag == Tag.nullTag)
Left(
ConstructError.from(
s"""|Could't construct ${classTag.runtimeClass.getName} from null (${node.tag.value})
|${node.pos.map(_.errorMsg).getOrElse("")}
|""".stripMargin
)
)
else if (pf.isDefinedAt(node)) pf(node)
else
Left(
ConstructError.from(
s"""|Could't construct ${classTag.runtimeClass.getName} from ${node.tag}
s"""|Could't construct ${classTag.runtimeClass.getName} from ${node.tag.value}
|${node.pos.map(_.errorMsg).getOrElse("")}
|""".stripMargin
)
Expand Down Expand Up @@ -198,11 +206,14 @@ object YamlDecoder extends YamlDecoderCompanionCrossCompat {
}
}

implicit def forOption[T](implicit c: YamlDecoder[T]): YamlDecoder[Option[T]] = YamlDecoder.from {
node =>
if (node.tag == Tag.nullTag) Right(None)
else c.construct(node).map(Option(_))
}
implicit def forOption[T](implicit c: YamlDecoder[T]): YamlDecoder[Option[T]] =
new YamlDecoder[Option[T]] {
override def construct(
node: Node
)(implicit settings: LoadSettings): Either[ConstructError, Option[T]] =
if (node.tag == Tag.nullTag) Right(None)
else c.construct(node).map(Option(_))
}

private def constructFromNodes[T](nodes: Seq[Node])(implicit
c: YamlDecoder[T]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,19 @@ class DecoderSuite extends munit.FunSuite:
case Right(value) =>
assertEquals(value, Map("value" -> 0.018256052173961423))
}

test("issue 120 - fail conversion of !!null to non-optional types") {
case class Foo(key1: Int, key2: Int) derives YamlDecoder

val yaml =
"""|key1: 1
|key2: !!null
|""".stripMargin

val bar = yaml.as[Foo]

bar match
case Left(error: YamlError) =>
assert(error.msg.contains("Could't construct int from null (tag:yaml.org,2002:null)"))
case Right(data) => fail(s"expected failure, but got: $data")
}

0 comments on commit a58465a

Please sign in to comment.