summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/strformat.nim38
-rw-r--r--tests/stdlib/tstrformat.nim24
-rw-r--r--tests/stdlib/tstrformatMissingFormatValue.nim16
3 files changed, 28 insertions, 50 deletions
diff --git a/lib/pure/strformat.nim b/lib/pure/strformat.nim
index a8ceecf3d..e12ca3c89 100644
--- a/lib/pure/strformat.nim
+++ b/lib/pure/strformat.nim
@@ -102,7 +102,9 @@ of ``formatValue`` procs. The required signature for a type ``T`` that supports
 formatting is usually ``proc formatValue(result: var string; x: T; specifier: string)``.
 
 The subexpression after the colon
-(``arg`` in ``&"{key} is {value:arg} {{z}}"``) is optional. It will be passed as the last argument to ``formatValue``. When the colon with the subexpression it is left out, an empty string will be taken instead.
+(``arg`` in ``&"{key} is {value:arg} {{z}}"``) is optional. It will be passed as
+the last argument to ``formatValue``. When the colon with the subexpression it is
+left out, an empty string will be taken instead.
 
 For strings and numeric types the optional argument is a so-called
 "standard format specifier".
@@ -215,8 +217,7 @@ Limitations
 ===========
 
 Because of the well defined order how templates and macros are
-expanded, strformat cannot expand template arguments.
-
+expanded, strformat cannot expand template arguments:
 
 .. code-block:: nim
   template myTemplate(arg: untyped): untyped =
@@ -233,27 +234,6 @@ quoted string literal. It is not an identifier yet. Then the strformat
 macro creates the ``arg`` identifier from the string literal. An
 identifier that cannot be resolved anymore.
 
-.. code-block:: nim
-  let x = "abc"
-  myTemplate(x)
-
-  # expansion of myTemplate
-
-  let x = "abc"
-  echo "arg is: ", x
-  echo &"--- {arg} ---"
-
-  # expansion of `&`
-
-  let x = "abc"
-  echo "arg is: ", x
-  echo:
-    var temp = newStringOfCap(20)
-    temp.add "--- "
-    temp.formatValue arg, "" # arg cannot be resolved anymore
-    temp.add " ---"
-    temp
-
 The workaround for this is to bind template argument to a new local variable.
 
 .. code-block:: nim
@@ -265,11 +245,12 @@ The workaround for this is to bind template argument to a new local variable.
       echo &"--- {arg1} ---"
 
 The use of ``{.inject.}`` here is necessary again because of template
-expansion order and hygienic templates. But since we generelly want to
+expansion order and hygienic templates. But since we generally want to
 keep the hygienicness of ``myTemplate``, and we do not want ``arg1``
 to be injected into the context where ``myTemplate`` is expanded,
 everything is wrapped in a ``block``.
 
+
 Future directions
 =================
 
@@ -522,8 +503,9 @@ proc formatValue*(result: var string; value: string; specifier: string) =
       setLen(value, runeOffset(value, spec.precision))
   result.add alignString(value, spec.minimumWidth, spec.align, spec.fill)
 
-template formatValue[T: enum](result: var string; value: T; specifier: string) =
-  result.add $value
+proc formatValue[T](result: var string; value: T; specifier: string) =
+  mixin `$`
+  formatValue(result, $value, specifier)
 
 template formatValue(result: var string; value: char; specifier: string) =
   result.add value
@@ -531,7 +513,7 @@ template formatValue(result: var string; value: char; specifier: string) =
 template formatValue(result: var string; value: cstring; specifier: string) =
   result.add value
 
-proc formatValue[T](result: var string; value: openarray[T]; specifier: string) =
+proc formatValue(result: var string; value: (array|seq|openArray); specifier: string) =
   result.add "["
   for i, it in value:
     if i != 0:
diff --git a/tests/stdlib/tstrformat.nim b/tests/stdlib/tstrformat.nim
index d99aeb2f1..86125ca00 100644
--- a/tests/stdlib/tstrformat.nim
+++ b/tests/stdlib/tstrformat.nim
@@ -1,5 +1,6 @@
 discard """
 action: "run"
+output: '''Received (name: "Foo", species: "Bar")'''
 """
 
 import strformat
@@ -64,16 +65,14 @@ doAssert fmt"{0.0: g}" == " 0"
 let data1 = [1'i64, 10000'i64, 10000000'i64]
 let data2 = [10000000'i64, 100'i64, 1'i64]
 
-doAssert fmt"data1: {data1:8} ∨" == "data1: [       1,    10000, 10000000] ∨"
-doAssert fmt"data2: {data2:8} ∧" == "data2: [10000000,      100,        1] ∧"
+doAssert fmt"data1: {data1:8} #" == "data1: [       1,    10000, 10000000] #"
+doAssert fmt"data2: {data2:8} =" == "data2: [10000000,      100,        1] ="
 
 # custom format Value
 
 type
   Vec2[T] = object
     x,y: T
-  Vec2f = Vec2[float32]
-  Vec2i = Vec2[int32]
 
 proc formatValue[T](result: var string; value: Vec2[T]; specifier: string) =
   result.add '['
@@ -82,8 +81,8 @@ proc formatValue[T](result: var string; value: Vec2[T]; specifier: string) =
   result.formatValue value.y, specifier
   result.add "]"
 
-let v1 = Vec2f(x:1.0, y: 2.0)
-let v2 = Vec2i(x:1, y: 1337)
+let v1 = Vec2[float32](x:1.0, y: 2.0)
+let v2 = Vec2[int32](x:1, y: 1337)
 doAssert fmt"v1: {v1:+08}  v2: {v2:>4}" == "v1: [+0000001, +0000002]  v2: [   1, 1337]"
 
 # issue #7632
@@ -94,3 +93,16 @@ doAssert works(5) == "formatted  5"
 doAssert fails0(6) == "formatted  6"
 doAssert fails(7) == "formatted  7"
 doAssert fails2[0](8) == "formatted  8"
+
+
+# bug #11012
+
+type
+  Animal = object
+    name, species: string
+  AnimalRef = ref Animal
+
+proc print_object(animalAddr: AnimalRef) =
+  echo fmt"Received {animalAddr[]}"
+
+print_object(AnimalRef(name: "Foo", species: "Bar"))
diff --git a/tests/stdlib/tstrformatMissingFormatValue.nim b/tests/stdlib/tstrformatMissingFormatValue.nim
deleted file mode 100644
index 66c1c8772..000000000
--- a/tests/stdlib/tstrformatMissingFormatValue.nim
+++ /dev/null
@@ -1,16 +0,0 @@
-discard """
-errormsg: '''type mismatch: got <string, Obj, string>'''
-nimout: '''proc formatValue'''
-"""
-
-# This test is here to make sure that there is a clean error that
-# that indicates ``formatValue`` needs to be overloaded with the custom type.
-
-import strformat
-
-type Obj = object
-
-proc `$`(o: Obj): string = "foobar"
-
-var o: Obj
-doAssert fmt"{o}" == "foobar"