Skip to content

Commit 70dab90

Browse files
committed
write tuples/objects
1 parent 41d928a commit 70dab90

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

lib/system/io.nim

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,76 @@ proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], benign.} =
380380
proc write*(f: File, c: char) {.tags: [WriteIOEffect], benign.} =
381381
discard c_putc(cint(c), f)
382382

383+
proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
384+
# Taken from typetraits.
385+
386+
proc writeEscapedChar(f: File, c: char) {.inline.} =
387+
# Analogue to `sysetm.addEscapedChar`.
388+
case c
389+
of '\a': f.write "\\a" # \x07
390+
of '\b': f.write "\\b" # \x08
391+
of '\t': f.write "\\t" # \x09
392+
of '\L': f.write "\\n" # \x0A
393+
of '\v': f.write "\\v" # \x0B
394+
of '\f': f.write "\\f" # \x0C
395+
of '\c': f.write "\\c" # \x0D
396+
of '\e': f.write "\\e" # \x1B
397+
of '\\': f.write("\\\\")
398+
of '\'': f.write("\\'")
399+
of '\"': f.write("\\\"")
400+
of {'\32'..'\126'} - {'\\', '\'', '\"'}: f.write(c)
401+
else:
402+
f.write("\\x")
403+
const HexChars = "0123456789ABCDEF"
404+
let n = ord(c)
405+
f.write(HexChars[int((n and 0xF0) shr 4)])
406+
f.write(HexChars[int(n and 0xF)])
407+
408+
proc writeQuoted[T](f: File, arg: T) =
409+
# analogue to `addQuoted` in `system`
410+
when T is string or T is cstring:
411+
f.write("\"")
412+
for c in arg:
413+
# Only ASCII chars are escaped to avoid butchering
414+
# multibyte UTF-8 characters.
415+
if c <= 127.char:
416+
f.writeEscapedChar(c)
417+
else:
418+
f.write c
419+
f.write("\"")
420+
elif T is char:
421+
f.write("'")
422+
f.addEscapedChar(x)
423+
f.write("'")
424+
# prevent temporary string allocation
425+
else:
426+
f.write(x)
427+
428+
proc write*[T: tuple|object](f: File; arg: T) =
429+
f.write "("
430+
const isNamed = isNamedTuple(T)
431+
var count = 0
432+
for name, value in fieldPairs(arg):
433+
if count != 0:
434+
f.write(", ")
435+
436+
when isNamed:
437+
f.write(name, ": ")
438+
439+
when compiles($value):
440+
when value isnot string and value isnot seq and compiles(value.isNil):
441+
if value.isNil: result.add "nil"
442+
else: f.writeQuoted(value)
443+
else:
444+
f.writeQuoted(value)
445+
else:
446+
f.write("...")
447+
inc count
448+
449+
if not isNamed and count == 1:
450+
f.write(",") # one tuple needs post comma, e.g. ``("abc",)``
451+
f.write(")")
452+
383453
when defined(harmfulOverloadOfWrite):
384454
proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], benign.} =
385455
for x in items(a): write(f, x)

0 commit comments

Comments
 (0)