@@ -1697,45 +1697,32 @@ impl<'a> Formatter<'a> {
16971697 if self . options . width . is_none ( ) && self . options . precision . is_none ( ) {
16981698 return self . buf . write_str ( s) ;
16991699 }
1700- // The `precision` field can be interpreted as a `max- width` for the
1700+ // The `precision` field can be interpreted as a maximum width for the
17011701 // string being formatted.
1702- let s = if let Some ( max) = self . options . precision {
1703- // If our string is longer that the precision, then we must have
1704- // truncation. However other flags like `fill`, `width` and `align`
1705- // must act as always.
1706- if let Some ( ( i, _) ) = s. char_indices ( ) . nth ( max) {
1707- // LLVM here can't prove that `..i` won't panic `&s[..i]`, but
1708- // we know that it can't panic. Use `get` + `unwrap_or` to avoid
1709- // `unsafe` and otherwise don't emit any panic-related code
1710- // here.
1711- s. get ( ..i) . unwrap_or ( s)
1712- } else {
1713- & s
1714- }
1702+ let max_chars_count = self . options . precision . unwrap_or ( usize:: MAX ) ;
1703+ let mut iter = s. chars ( ) ;
1704+ let chars_count = iter. by_ref ( ) . take ( max_chars_count) . count ( ) ;
1705+
1706+ // If our string is longer than the maximum width, truncate it and
1707+ // handle other flags in terms of the truncated string.
1708+ let byte_len = s. len ( ) - iter. as_str ( ) . len ( ) ;
1709+ // SAFETY: `char_indices` guarantees the index is in-bounds and between
1710+ // character boundaries.
1711+ let s = unsafe { s. get_unchecked ( ..byte_len) } ;
1712+
1713+ // The `width` field is more of a minimum width parameter at this point.
1714+ if let Some ( width) = self . options . width
1715+ && chars_count < width
1716+ {
1717+ // If we're under the minimum width, then fill up the minimum width
1718+ // with the specified string + some alignment.
1719+ let post_padding = self . padding ( width - chars_count, Alignment :: Left ) ?;
1720+ self . buf . write_str ( s) ?;
1721+ post_padding. write ( self )
17151722 } else {
1716- & s
1717- } ;
1718- // The `width` field is more of a `min-width` parameter at this point.
1719- match self . options . width {
1720- // If we're under the maximum length, and there's no minimum length
1721- // requirements, then we can just emit the string
1722- None => self . buf . write_str ( s) ,
1723- Some ( width) => {
1724- let chars_count = s. chars ( ) . count ( ) ;
1725- // If we're under the maximum width, check if we're over the minimum
1726- // width, if so it's as easy as just emitting the string.
1727- if chars_count >= width {
1728- self . buf . write_str ( s)
1729- }
1730- // If we're under both the maximum and the minimum width, then fill
1731- // up the minimum width with the specified string + some alignment.
1732- else {
1733- let align = Alignment :: Left ;
1734- let post_padding = self . padding ( width - chars_count, align) ?;
1735- self . buf . write_str ( s) ?;
1736- post_padding. write ( self )
1737- }
1738- }
1723+ // If we're over the minimum width or there is no minimum width, we
1724+ // can just emit the string.
1725+ self . buf . write_str ( s)
17391726 }
17401727 }
17411728
0 commit comments