Skip to content

Commit 4ad3807

Browse files
authored
pretty-printer for Duration (#547)
1 parent 7630f39 commit 4ad3807

File tree

2 files changed

+37
-45
lines changed

2 files changed

+37
-45
lines changed

chronos/timer.nim

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -370,53 +370,42 @@ template add(a: var string, b: Base10Buf[uint64]) =
370370
for index in 0 ..< b.len:
371371
a.add(char(b.data[index]))
372372

373-
func `$`*(a: Duration): string {.inline.} =
374-
## Returns string representation of Duration ``a`` as nanoseconds value.
375-
var res = ""
376-
var v = a.value
377-
378-
if v >= Week.value:
379-
res.add(Base10.toBytes(uint64(v div Week.value)))
380-
res.add('w')
381-
v = v mod Week.value
382-
if v == 0: return res
383-
if v >= Day.value:
384-
res.add(Base10.toBytes(uint64(v div Day.value)))
385-
res.add('d')
386-
v = v mod Day.value
387-
if v == 0: return res
388-
if v >= Hour.value:
389-
res.add(Base10.toBytes(uint64(v div Hour.value)))
390-
res.add('h')
391-
v = v mod Hour.value
392-
if v == 0: return res
393-
if v >= Minute.value:
394-
res.add(Base10.toBytes(uint64(v div Minute.value)))
395-
res.add('m')
396-
v = v mod Minute.value
397-
if v == 0: return res
398-
if v >= Second.value:
399-
res.add(Base10.toBytes(uint64(v div Second.value)))
400-
res.add('s')
401-
v = v mod Second.value
402-
if v == 0: return res
403-
if v >= Millisecond.value:
404-
res.add(Base10.toBytes(uint64(v div Millisecond.value)))
405-
res.add('m')
406-
res.add('s')
407-
v = v mod Millisecond.value
408-
if v == 0: return res
409-
if v >= Microsecond.value:
410-
res.add(Base10.toBytes(uint64(v div Microsecond.value)))
411-
res.add('u')
412-
res.add('s')
413-
v = v mod Microsecond.value
414-
if v == 0: return res
415-
res.add(Base10.toBytes(uint64(v div Nanosecond.value)))
416-
res.add('n')
417-
res.add('s')
373+
func toString*(a: timer.Duration, parts = int.high): string =
374+
## Returns a pretty string representation of Duration ``a`` - the
375+
## number of parts returned can be limited thus truncating the output to
376+
## an approximation that grows more precise as the duration becomes smaller
377+
var
378+
res = newStringOfCap(32)
379+
v = a.nanoseconds()
380+
parts = parts
381+
382+
template f(n: string, T: Duration) =
383+
if parts <= 0:
384+
return res
385+
386+
if v >= T.nanoseconds():
387+
res.add(Base10.toBytes(uint64(v div T.nanoseconds())))
388+
res.add(n)
389+
v = v mod T.nanoseconds()
390+
dec parts
391+
if v == 0:
392+
return res
393+
394+
f("w", Week)
395+
f("d", Day)
396+
f("h", Hour)
397+
f("m", Minute)
398+
f("s", Second)
399+
f("ms", Millisecond)
400+
f("us", Microsecond)
401+
f("ns", Nanosecond)
402+
418403
res
419404

405+
func `$`*(a: Duration): string {.inline.} =
406+
## Returns string representation of Duration ``a``.
407+
a.toString()
408+
420409
func `$`*(a: Moment): string {.inline.} =
421410
## Returns string representation of Moment ``a`` as nanoseconds value.
422411
var res = ""

tests/testtime.nim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ suite "Asynchronous timers & steps test suite":
8989
$nanoseconds(1_000_000_900) == "1s900ns"
9090
$nanoseconds(1_800_700_000) == "1s800ms700us"
9191
$nanoseconds(1_800_000_600) == "1s800ms600ns"
92+
nanoseconds(1_800_000_600).toString(0) == ""
93+
nanoseconds(1_800_000_600).toString(1) == "1s"
94+
nanoseconds(1_800_000_600).toString(2) == "1s800ms"
9295

9396
test "Asynchronous steps test":
9497
var fut1 = stepsAsync(1)

0 commit comments

Comments
 (0)