summary refs log tree commit diff
path: root/src/libcore/fmt
diff options
context:
space:
mode:
authorEvgeny Safronov <division494@gmail.com>2016-06-29 10:40:25 +0300
committerEvgeny Safronov <division494@gmail.com>2016-07-06 00:01:14 +0300
commitede39aeb331bf6efb3739d22a60c1844e9c2c3d6 (patch)
treebcd62c0edd6afb3fbd803e28c5f1cf627d97ede4 /src/libcore/fmt
parentea0dc9297283daff6486807f43e190b4eb561412 (diff)
downloadrust-ede39aeb331bf6efb3739d22a60c1844e9c2c3d6.tar.gz
rust-ede39aeb331bf6efb3739d22a60c1844e9c2c3d6.zip
feat: reinterpret `precision` field for strings
This commit changes the behavior of formatting string arguments
with both width and precision fields set.

Documentation says that the `width` field is the "minimum width"
that the format should take up. If the value's string does not
fill up this many characters, then the padding specified by
fill/alignment will be used to take up the required space.

This is true for all formatted types except string, which is truncated
down to `precision` number of chars and then all of `fill`, `align` and
`width` fields are completely ignored.

For example: `format!("{:/^10.8}", "1234567890);` emits "12345678".
In the contrast Python version works as the expected:
```python
>>> '{:/^10.8}'.format('1234567890')
'/12345678/'
```

This commit gives back the `Python` behavior by changing the `precision`
field meaning to the truncation and nothing more. The result string *will*
be prepended/appended up to the `width` field with the proper `fill` char.

However, this is the breaking change.

Also updated `std::fmt` docs about string precision.

Signed-off-by: Evgeny Safronov <division494@gmail.com>
Diffstat (limited to 'src/libcore/fmt')
-rw-r--r--src/libcore/fmt/mod.rs18
1 files changed, 11 insertions, 7 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 4ac134c2b59..a36f7e42c9c 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -983,15 +983,19 @@ impl<'a> Formatter<'a> {
             return self.buf.write_str(s);
         }
         // The `precision` field can be interpreted as a `max-width` for the
-        // string being formatted
-        if let Some(max) = self.precision {
-            // If there's a maximum width and our string is longer than
-            // that, then we must always have truncation. This is the only
-            // case where the maximum length will matter.
+        // string being formatted.
+        let s = if let Some(max) = self.precision {
+            // If our string is longer that the precision, then we must have
+            // truncation. However other flags like `fill`, `width` and `align`
+            // must act as always.
             if let Some((i, _)) = s.char_indices().skip(max).next() {
-                return self.buf.write_str(&s[..i])
+                &s[..i]
+            } else {
+                &s
             }
-        }
+        } else {
+            &s
+        };
         // The `width` field is more of a `min-width` parameter at this point.
         match self.width {
             // If we're under the maximum length, and there's no minimum length