reader support for stringlikes

This commit is contained in:
Jacek Sieka 2020-04-29 10:21:20 +02:00 committed by zah
parent e485b74a10
commit cb695d175f
3 changed files with 30 additions and 3 deletions

View File

@ -1,6 +1,6 @@
import import
unicode, unicode,
faststreams/input_stream, stew/objects, faststreams/input_stream,
types types
export export

View File

@ -169,6 +169,12 @@ func maxAbsValue(T: type[SomeInteger]): uint64 {.compileTime.} =
proc isNotNilCheck[T](x: ref T not nil) {.compileTime.} = discard proc isNotNilCheck[T](x: ref T not nil) {.compileTime.} = discard
proc isNotNilCheck[T](x: ptr T not nil) {.compileTime.} = discard proc isNotNilCheck[T](x: ptr T not nil) {.compileTime.} = discard
# this construct catches `array[N, char]` which otherwise won't decompose into
# openArray[char] - we treat any array-like thing-of-characters as a string in
# the output
template isCharArray[N](v: array[N, char]): bool = true
template isCharArray(v: auto): bool = false
proc readValue*(r: var JsonReader, value: var auto) = proc readValue*(r: var JsonReader, value: var auto) =
mixin readValue mixin readValue
@ -178,7 +184,20 @@ proc readValue*(r: var JsonReader, value: var auto) =
r.requireToken tkString r.requireToken tkString
value = r.lexer.strVal value = r.lexer.strVal
r.lexer.next() r.lexer.next()
elif value is seq[char]:
r.requireToken tkString
value.setLen(r.lexer.strVal.len)
for i in 0..<r.lexer.strVal.len:
value[i] = r.lexer.strVal[i]
r.lexer.next()
elif isCharArray(value):
r.requireToken tkString
if r.lexer.strVal.len != value.len:
# Raise tkString because we expected a `"` earlier
r.raiseUnexpectedToken(etString)
for i in 0..<value.len:
value[i] = r.lexer.strVal[i]
r.lexer.next()
elif value is bool: elif value is bool:
case tok case tok
of tkTrue: value = true of tkTrue: value = true

View File

@ -149,8 +149,16 @@ suite "toJson tests":
check: check:
$original == $decoded $original == $decoded
test "openArray[char]": test "stringLike":
check: check:
"abc" == Json.decode(Json.encode(['a', 'b', 'c']), string) "abc" == Json.decode(Json.encode(['a', 'b', 'c']), string)
"abc" == Json.decode(Json.encode(@['a', 'b', 'c']), string) "abc" == Json.decode(Json.encode(@['a', 'b', 'c']), string)
['a', 'b', 'c'] == Json.decode(Json.encode(@['a', 'b', 'c']), seq[char])
['a', 'b', 'c'] == Json.decode(Json.encode("abc"), seq[char])
['a', 'b', 'c'] == Json.decode(Json.encode(@['a', 'b', 'c']), array[3, char])
expect JsonReaderError: # too short
discard Json.decode(Json.encode(@['a', 'b']), array[3, char])
expect JsonReaderError: # too long
discard Json.decode(Json.encode(@['a', 'b']), array[1, char])