This commit is contained in:
2025-09-22 13:02:35 +02:00
parent c32b20e5b3
commit 5b95c4dd64
41 changed files with 998 additions and 152 deletions

View File

@@ -3,10 +3,12 @@ package blitz.parse
import blitz.collections.RefVec
import blitz.collections.contents
import blitz.parse.comb2.*
import blitz.test.annotations.Test
import blitz.test.util.requireEqual
import blitz.unreachable
@Suppress("NOTHING_TO_INLINE")
object JSON {
val jsonBool: Parser<Char, Element> = choose {
it(mapValue(seq("true".toList())) { Element.newBool(true) })
it(mapValue(seq("false".toList())) { Element.newBool(false) })
@@ -116,31 +118,72 @@ object JSON {
inline fun Element.uncheckedAsObj(): Map<String, Element> =
_boxed as Map<String, Element>
inline fun Element.asNum(): Double {
fun Element.asNum(): Double {
require(kind == Element.NUM) { "Element is not a Number" }
return _num
}
inline fun Element.asBool(): Boolean {
fun Element.asBool(): Boolean {
require(kind == Element.BOOL) { "Element is not a Boolean" }
return _bool
}
inline fun Element.asArr(): RefVec<Element> {
fun Element.asArr(): RefVec<Element> {
require(kind == Element.ARR) { "Element is not an Array" }
return _boxed as RefVec<Element>
}
inline fun Element.asStr(): String {
fun Element.asStr(): String {
require(kind == Element.STR) { "Element is not a String" }
return _boxed as String
}
inline fun Element.asObj(): Map<String, Element> {
fun Element.asObj(): Map<String, Element> {
require(kind == Element.OBJ) { "Element is not an Object" }
return _boxed as Map<String, Element>
}
fun parse(string: String): ParseResult<Element> =
jsonElement.run(string.toList())
object _tests {
@Test
fun parseJsonNumber() {
parse("-1.351").assertA().asNum()
.requireEqual(-1.351)
}
@Test
fun parseJsonBool() {
parse("true").assertA().asBool()
.requireEqual(true)
parse("false").assertA().asBool()
.requireEqual(false)
}
@Test
fun parseJsonNull() {
parse("null").assertA().kind
.requireEqual(Element.NULL)
}
@Test
fun parseJsonStr() {
parse("\"Hello\\\n\\\"aworld\"").assertA().asStr()
.requireEqual("Hello\n\"aworld")
}
@Test
fun parseJsonArr() {
parse("[1, 2, 3,\n 4]").assertA().asArr()
.map { it.asNum() }.contents.requireEqual(listOf(1.0,2.0,3.0,4.0).contents)
}
@Test
fun parseJsonObj() {
val obj = parse("{\"a\": 1, \"b\": 2}").assertA().asObj()
obj.map { it.value.asNum() }.contents.requireEqual(listOf(1.0,2.0).contents)
obj.map { it.key }.contents.requireEqual(listOf("a","b").contents)
}
}
}