diff --git a/core/shared/src/main/scala/org/virtuslab/yaml/Tag.scala b/core/shared/src/main/scala/org/virtuslab/yaml/Tag.scala index fec72beb..4b6b6388 100644 --- a/core/shared/src/main/scala/org/virtuslab/yaml/Tag.scala +++ b/core/shared/src/main/scala/org/virtuslab/yaml/Tag.scala @@ -1,5 +1,8 @@ package org.virtuslab.yaml +import org.virtuslab.yaml.internal.load.reader.token.ScalarStyle +import org.virtuslab.yaml.internal.load.reader.token.ScalarStyle.{DoubleQuoted, SingleQuoted} + import scala.reflect.ClassTag sealed trait Tag { @@ -35,9 +38,11 @@ object Tag { private val minusInfinity = "-(\\.inf|\\.Inf|\\.INF)".r private val plusInfinity = "\\+?(\\.inf|\\.Inf|\\.INF)".r - def resolveTag(value: String): Tag = { + def resolveTag(value: String, style: Option[ScalarStyle] = None): Tag = { + val assumeString = style.exists(s => s == DoubleQuoted || s == SingleQuoted) value match { case null => nullTag + case _ if assumeString => str case nullPattern(_*) => nullTag case booleanPattern(_*) => boolean case int10Pattern(_*) => int diff --git a/core/shared/src/main/scala/org/virtuslab/yaml/internal/load/compose/Composer.scala b/core/shared/src/main/scala/org/virtuslab/yaml/internal/load/compose/Composer.scala index 410a4e37..0d8df42b 100644 --- a/core/shared/src/main/scala/org/virtuslab/yaml/internal/load/compose/Composer.scala +++ b/core/shared/src/main/scala/org/virtuslab/yaml/internal/load/compose/Composer.scala @@ -47,7 +47,7 @@ object ComposerImpl extends Composer { case EventKind.MappingStart(NodeEventMetadata(anchor, _)) => composeMappingNode(tail, anchor, aliases) case s: EventKind.Scalar => - val tag: Tag = s.metadata.tag.getOrElse(Tag.resolveTag(s.value)) + val tag: Tag = s.metadata.tag.getOrElse(Tag.resolveTag(s.value, Some(s.style))) val node = Node.ScalarNode(s.value, tag, head.pos) s.metadata.anchor.foreach(anchor => aliases.put(anchor, node)) Right(Result(node, tail)) diff --git a/core/shared/src/test/scala/org/virtuslab/yaml/parser/ScalarSuite.scala b/core/shared/src/test/scala/org/virtuslab/yaml/parser/ScalarSuite.scala index d4e2efdc..6f0dea90 100644 --- a/core/shared/src/test/scala/org/virtuslab/yaml/parser/ScalarSuite.scala +++ b/core/shared/src/test/scala/org/virtuslab/yaml/parser/ScalarSuite.scala @@ -458,4 +458,54 @@ class ScalarSpec extends BaseYamlSuite { ) assertEquals(yaml.events, Right(expectedEvents)) } + test("quoted integer and bool values") { + val yaml = + """ + | - "123" + | - "bool" + | - 'bool' + | - "0xFFFF" + | - 123 + | - bool + | - 0xFFFF + | """.stripMargin + val expectedEvents = List( + StreamStart, + DocumentStart(), + SequenceStart(), + Scalar("123", ScalarStyle.DoubleQuoted), + Scalar("bool", ScalarStyle.DoubleQuoted), + Scalar("bool", ScalarStyle.SingleQuoted), + Scalar("0xFFFF", ScalarStyle.DoubleQuoted), + Scalar("123", ScalarStyle.Plain), + Scalar("bool", ScalarStyle.Plain), + Scalar("0xFFFF", ScalarStyle.Plain), + SequenceEnd, + DocumentEnd(), + StreamEnd + ) + assertEquals(yaml.events, Right(expectedEvents)) + } + + test("quoted values are read as String type") { + import org.virtuslab.yaml.{StringOps ⇒ SO, _} + val isStringType: Seq[Boolean] = Seq( + """ "123" """, + """ "0xFFFF" """, + """ "true" """, + """ "null" """, + """ "123.456" """, + """ "-.inf" """, + """ '123' """, + """ '0xFFFF' """, + """ 'true' """, + """ 'null' """, + """ '123.456' """, + """ '-.inf' """ + ).map { yaml => + val obj = SO(yaml).as[Any].toOption.get + obj.isInstanceOf[java.lang.String] + } + assertEquals(isStringType, Seq.fill(isStringType.length)(true)) + } }