diff options
Diffstat (limited to 'lib/std')
-rw-r--r-- | lib/std/objectdollar.nim | 11 | ||||
-rw-r--r-- | lib/std/private/miscdollars.nim | 39 |
2 files changed, 50 insertions, 0 deletions
diff --git a/lib/std/objectdollar.nim b/lib/std/objectdollar.nim new file mode 100644 index 000000000..f413bbc46 --- /dev/null +++ b/lib/std/objectdollar.nim @@ -0,0 +1,11 @@ +import std/private/miscdollars + +proc `$`*[T: object](x: T): string = + ## Generic `$` operator for objects with similar output to + ## `$` for named tuples. + runnableExamples: + type Foo = object + a, b: int + let x = Foo(a: 23, b: 45) + assert $x == "(a: 23, b: 45)" + tupleObjectDollar(result, x) diff --git a/lib/std/private/miscdollars.nim b/lib/std/private/miscdollars.nim index 840fedf54..47b788ee9 100644 --- a/lib/std/private/miscdollars.nim +++ b/lib/std/private/miscdollars.nim @@ -12,3 +12,42 @@ template toLocation*(result: var string, file: string | cstring, line: int, col: result.add ", " addInt(result, col) result.add ")" + +when defined(nimHasIsNamedTuple): + proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".} +else: + # for bootstrap; remove after release 1.2 + proc isNamedTuple(T: typedesc): bool = + # Taken from typetraits. + when T isnot tuple: result = false + else: + var t: T + for name, _ in t.fieldPairs: + when name == "Field0": + return compiles(t.Field0) + else: + return true + return false + +template tupleObjectDollar*[T: tuple | object](result: var string, x: T) = + result = "(" + const isNamed = T is object or isNamedTuple(typeof(T)) + var count {.used.} = 0 + for name, value in fieldPairs(x): + if count > 0: result.add(", ") + when isNamed: + result.add(name) + result.add(": ") + count.inc + when compiles($value): + when value isnot string and value isnot seq and compiles(value.isNil): + if value.isNil: result.add "nil" + else: result.addQuoted(value) + else: + result.addQuoted(value) + else: + result.add("...") + when not isNamed: + if count == 1: + result.add(",") # $(1,) should print as the semantically legal (1,) + result.add(")") |