Replace concat with writeText

Write to a stream rather than concatentate a string.
This commit is contained in:
Emery Hemingway 2022-10-28 22:12:12 -05:00
parent 7e72c2a515
commit 11661d453c
2 changed files with 54 additions and 50 deletions

View File

@ -1188,80 +1188,84 @@ proc mapEmbeds*[A, B](pr: sink Preserve[A]; op: proc (v: A): B): Preserve[B] =
of pkEmbedded:
result = embed op(pr.embed)
proc concat[E](result: var string; pr: Preserve[E]) =
if pr.embedded: result.add("#!")
proc writeText*[E](stream: Stream; pr: Preserve[E]) =
## Encode Preserves to a `Stream` as text.
if pr.embedded: write(stream, "#!")
case pr.kind:
of pkBoolean:
case pr.bool
of false: result.add "#f"
of true: result.add "#t"
of false: write(stream, "#f")
of true: write(stream, "#t")
of pkFloat:
result.add($pr.float & "f")
write(stream, $pr.float)
write(stream, 'f')
of pkDouble:
result.add $pr.double
write(stream, $pr.double)
of pkSignedInteger:
result.add $pr.int
write(stream, $pr.int)
of pkString:
result.add escapeJson(pr.string)
write(stream, escapeJson(pr.string))
of pkByteString:
if pr.bytes.allIt(char(it) in {' '..'!', '#'..'~'}):
result.add("#\"")
result.add(cast[string](pr.bytes))
result.add('"')
write(stream, "#\"")
write(stream, cast[string](pr.bytes))
write(stream, '"')
else:
if pr.bytes.len > 64:
result.add("#[") #]#
result.add(base64.encode(pr.bytes))
result.add(']')
write(stream, "#[") #]#
write(stream, base64.encode(pr.bytes))
write(stream, ']')
else:
const alphabet = "0123456789abcdef"
result.add("#x\"")
write(stream, "#x\"")
for b in pr.bytes:
result.add(alphabet[int(b shr 4)])
result.add(alphabet[int(b and 0xf)])
result.add('"')
write(stream, alphabet[int(b shr 4)])
write(stream, alphabet[int(b and 0xf)])
write(stream, '"')
of pkSymbol:
result.add(escapeJsonUnquoted(string pr.symbol))
write(stream, escapeJsonUnquoted(string pr.symbol))
of pkRecord:
assert(pr.record.len > 0)
result.add('<')
result.concat(pr.record[pr.record.high])
write(stream, '<')
writeText(stream, pr.record[pr.record.high])
for i in 0..<pr.record.high:
result.add(' ')
result.concat(pr.record[i])
result.add('>')
write(stream, ' ')
writeText(stream, pr.record[i])
write(stream, '>')
of pkSequence:
result.add('[')
for i, val in pr.sequence:
if i > 0: result.add(' ')
result.concat(val)
result.add(']')
write(stream, '[')
var insertWhitespace: bool
for val in pr.sequence:
if insertWhitespace: write(stream, ' ')
else: insertWhitespace = true
writeText(stream, val)
write(stream, ']')
of pkSet:
result.add("#{")
write(stream, "#{")
var insertWhitespace: bool
for val in pr.set.items:
result.concat(val)
result.add(' ')
if pr.set.len > 1:
result.setLen(result.high)
result.add('}')
if insertWhitespace: write(stream, ' ')
else: insertWhitespace = true
writeText(stream, val)
write(stream, '}')
of pkDictionary:
result.add('{')
var i = 0
write(stream, '{')
var insertWhitespace: bool
for (key, value) in pr.dict.items:
if i > 0:
result.add(' ')
result.concat(key)
result.add(": ")
result.concat(value)
if i < pr.dict.high:
result.add(',')
inc i
result.add('}')
if insertWhitespace: write(stream, ' ')
else: insertWhitespace = true
writeText(stream, key)
write(stream, ": ")
writeText(stream, value)
write(stream, '}')
of pkEmbedded:
result.add("#!")
result.add($pr.embed)
write(stream, "#!")
write(stream, $pr.embed)
proc `$`*(pr: Preserve): string = concat(result, pr)
proc `$`*[E](pr: Preserve[E]): string =
## Generate the textual representation of ``pr``.
var stream = newStringStream()
writeText(stream, pr)
result = move stream.data
include ./preserves/private/parse

View File

@ -35,7 +35,7 @@ suite "conversions":
var a: Table[int, string]
for i, s in ["a", "b", "c"]: a[i] = s
let b = toPreserve(a)
check($b == """{0: "a", 1: "b", 2: "c"}""")
check($b == """{0: "a" 1: "b" 2: "c"}""")
var c: Table[int, string]
check(fromPreserve(c, b))
check(a == c)