Skip to content

Commit 04b17f0

Browse files
committed
feat(api): strformat
1 parent 9756652 commit 04b17f0

1 file changed

Lines changed: 35 additions & 9 deletions

File tree

src/pycomplex.nim

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ runnableExamples:
1010
# just as Python's
1111
assert not (type(complex(1, 2).real) is int)
1212

13+
import std/strformat
1314
import std/complex as ncomplex except im, complex, pow
1415
export ncomplex.`/` # XXX: NIM-BUG: or
1516
#[ lib/pure/complex.nim's `func inv*[T](z: Complex[T])` will:
@@ -42,14 +43,23 @@ template borrowAttr(expAs, attr){.dirty.} =
4243
borrowAttr imag, im
4344
borrowAttr real, re
4445

46+
func cut2str(result: var string) =
47+
let lm2 = result.len - 2
48+
if result[lm2+1] == '0' and result[lm2] == '.':
49+
result.setLen lm2
4550
func cut2str[T: SomeFloat](x: T): string =
4651
# Nim's Complex's elements can only be of float
4752
result = floatdollar.`$` x
4853
# removesuffix('.0')
4954
# We know $<float> will be at least 3 chars (e.g. "0.0", "inf")
50-
let lm2 = result.len - 2
51-
if result[lm2+1] == '0' and result[lm2] == '.':
52-
result.setLen lm2
55+
result.cut2str
56+
57+
template requirePlus(x: float): bool =
58+
# act as `PyOS_double_to_string` with flag of `Py_DTSF_SIGN`
59+
x >= 0 or x.isNaN
60+
# NOTE: CPython's implementation does not care the sign of NaN here,
61+
# unconsistent with cases in other places
62+
# (CPython is used to caring a lot the sign of NaN)
5363

5464
func repr*(z: PyTComplex): string =
5565
## Returns `bj/(a+bj)`/`(a-bj)` for `complex(a, b)`
@@ -70,12 +80,6 @@ func repr*(z: PyTComplex): string =
7080
return
7181
result.add '('
7282
result.add real.cut2str
73-
template requirePlus(x: float): bool =
74-
# act as `PyOS_double_to_string` with flag of `Py_DTSF_SIGN`
75-
x >= 0 or x.isNaN
76-
# NOTE: CPython's implementation does not care the sign of NaN here,
77-
# unconsistent with cases in other places
78-
# (CPython is used to caring a lot the sign of NaN)
7983
if requirePlus imag:
8084
result.add '+'
8185
# if negative, `-` will be prefix-ed by `$`
@@ -84,6 +88,28 @@ func repr*(z: PyTComplex): string =
8488

8589
func `$`*(z: PyTComplex): string = repr z
8690

91+
proc formatValue*(res: var string, z: PyTComplex, spec: string) =
92+
## format complex with given spec, e.g. `format(complex(1, 2), ".2f")` -> "1.00+2.00j"
93+
##
94+
## Note that Python's `format` does not support `e`/`E` for complex, but Nim's does.
95+
## So we support it as well.
96+
template addImag =
97+
res.formatValue z.imag, spec
98+
res.cut2str
99+
res.add 'j'
100+
101+
if z.real == 0.0 and copySign(1.0, z.real) == 1.0: # +0.0
102+
addImag
103+
return
104+
105+
res.add '('
106+
res.formatValue z.real, spec
107+
res.cut2str
108+
if requirePlus z.imag:
109+
res.add '+'
110+
addImag
111+
res.add ')'
112+
87113
template toPyComplex[T](z: ncomplex.Complex[T]): PyTComplex[T] =
88114
## Convert Nim's Complex in std/complex to PyTComplex
89115
bind PyTComplex

0 commit comments

Comments
 (0)