Skip to content

Commit e38639f

Browse files
authored
Rollup merge of #65332 - RalfJung:fmt, r=cramertj
std::fmt: reorder docs This moves the "Formatting Parameters" section up above right after the discussion of named and positional arguments. Then comes the "Syntax" section, summarizing the discussion of format string syntax. And only *then* we get to "Formatting Traits" -- that section has some *huge* code examples, so it really should not interrupt the discussion of the grammar. Also users are much more likely to come here to learn about the format string grammar than to come here to learn about the `Binary` trait.
2 parents 6d28ed1 + 504cc20 commit e38639f

File tree

1 file changed

+175
-191
lines changed

1 file changed

+175
-191
lines changed

src/liballoc/fmt.rs

+175-191
Original file line numberDiff line numberDiff line change
@@ -80,24 +80,187 @@
8080
//! arguments which have names. Like with positional parameters, it is not
8181
//! valid to provide named parameters that are unused by the format string.
8282
//!
83-
//! ## Argument types
83+
//! # Formatting Parameters
84+
//!
85+
//! Each argument being formatted can be transformed by a number of formatting
86+
//! parameters (corresponding to `format_spec` in the syntax above). These
87+
//! parameters affect the string representation of what's being formatted.
88+
//!
89+
//! ## Fill/Alignment
90+
//!
91+
//! The fill character is provided normally in conjunction with the
92+
//! [`width`](#width)
93+
//! parameter. This indicates that if the value being formatted is smaller than
94+
//! `width` some extra characters will be printed around it. The extra
95+
//! characters are specified by `fill`, and the alignment can be one of the
96+
//! following options:
97+
//!
98+
//! * `<` - the argument is left-aligned in `width` columns
99+
//! * `^` - the argument is center-aligned in `width` columns
100+
//! * `>` - the argument is right-aligned in `width` columns
101+
//!
102+
//! Note that alignment may not be implemented by some types. In particular, it
103+
//! is not generally implemented for the `Debug` trait. A good way to ensure
104+
//! padding is applied is to format your input, then use this resulting string
105+
//! to pad your output.
106+
//!
107+
//! ## Sign/`#`/`0`
108+
//!
109+
//! These can all be interpreted as flags for a particular formatter.
110+
//!
111+
//! * `+` - This is intended for numeric types and indicates that the sign
112+
//! should always be printed. Positive signs are never printed by
113+
//! default, and the negative sign is only printed by default for the
114+
//! `Signed` trait. This flag indicates that the correct sign (`+` or `-`)
115+
//! should always be printed.
116+
//! * `-` - Currently not used
117+
//! * `#` - This flag is indicates that the "alternate" form of printing should
118+
//! be used. The alternate forms are:
119+
//! * `#?` - pretty-print the [`Debug`] formatting
120+
//! * `#x` - precedes the argument with a `0x`
121+
//! * `#X` - precedes the argument with a `0x`
122+
//! * `#b` - precedes the argument with a `0b`
123+
//! * `#o` - precedes the argument with a `0o`
124+
//! * `0` - This is used to indicate for integer formats that the padding should
125+
//! both be done with a `0` character as well as be sign-aware. A format
126+
//! like `{:08}` would yield `00000001` for the integer `1`, while the
127+
//! same format would yield `-0000001` for the integer `-1`. Notice that
128+
//! the negative version has one fewer zero than the positive version.
129+
//! Note that padding zeroes are always placed after the sign (if any)
130+
//! and before the digits. When used together with the `#` flag, a similar
131+
//! rule applies: padding zeroes are inserted after the prefix but before
132+
//! the digits.
133+
//!
134+
//! ## Width
135+
//!
136+
//! This is a parameter for the "minimum width" that the format should take up.
137+
//! If the value's string does not fill up this many characters, then the
138+
//! padding specified by fill/alignment will be used to take up the required
139+
//! space.
140+
//!
141+
//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
142+
//! left-aligned. The
143+
//! defaults for numeric formatters is also a space but with right-alignment. If
144+
//! the `0` flag is specified for numerics, then the implicit fill character is
145+
//! `0`.
146+
//!
147+
//! The value for the width can also be provided as a [`usize`] in the list of
148+
//! parameters by using the dollar syntax indicating that the second argument is
149+
//! a [`usize`] specifying the width, for example:
150+
//!
151+
//! ```
152+
//! // All of these print "Hello x !"
153+
//! println!("Hello {:5}!", "x");
154+
//! println!("Hello {:1$}!", "x", 5);
155+
//! println!("Hello {1:0$}!", 5, "x");
156+
//! println!("Hello {:width$}!", "x", width = 5);
157+
//! ```
158+
//!
159+
//! Referring to an argument with the dollar syntax does not affect the "next
160+
//! argument" counter, so it's usually a good idea to refer to arguments by
161+
//! position, or use named arguments.
162+
//!
163+
//! ## Precision
164+
//!
165+
//! For non-numeric types, this can be considered a "maximum width". If the resulting string is
166+
//! longer than this width, then it is truncated down to this many characters and that truncated
167+
//! value is emitted with proper `fill`, `alignment` and `width` if those parameters are set.
168+
//!
169+
//! For integral types, this is ignored.
170+
//!
171+
//! For floating-point types, this indicates how many digits after the decimal point should be
172+
//! printed.
173+
//!
174+
//! There are three possible ways to specify the desired `precision`:
175+
//!
176+
//! 1. An integer `.N`:
177+
//!
178+
//! the integer `N` itself is the precision.
179+
//!
180+
//! 2. An integer or name followed by dollar sign `.N$`:
181+
//!
182+
//! use format *argument* `N` (which must be a `usize`) as the precision.
183+
//!
184+
//! 3. An asterisk `.*`:
185+
//!
186+
//! `.*` means that this `{...}` is associated with *two* format inputs rather than one: the
187+
//! first input holds the `usize` precision, and the second holds the value to print. Note that
188+
//! in this case, if one uses the format string `{<arg>:<spec>.*}`, then the `<arg>` part refers
189+
//! to the *value* to print, and the `precision` must come in the input preceding `<arg>`.
190+
//!
191+
//! For example, the following calls all print the same thing `Hello x is 0.01000`:
192+
//!
193+
//! ```
194+
//! // Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)}
195+
//! println!("Hello {0} is {1:.5}", "x", 0.01);
196+
//!
197+
//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)}
198+
//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
199+
//!
200+
//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)}
201+
//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
202+
//!
203+
//! // Hello {next arg ("x")} is {second of next two args (0.01) with precision
204+
//! // specified in first of next two args (5)}
205+
//! println!("Hello {} is {:.*}", "x", 5, 0.01);
206+
//!
207+
//! // Hello {next arg ("x")} is {arg 2 (0.01) with precision
208+
//! // specified in its predecessor (5)}
209+
//! println!("Hello {} is {2:.*}", "x", 5, 0.01);
210+
//!
211+
//! // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified
212+
//! // in arg "prec" (5)}
213+
//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
214+
//! ```
84215
//!
85-
//! Each argument's type is dictated by the format string.
86-
//! There are various parameters which require a particular type, however.
87-
//! An example is the `{:.*}` syntax, which sets the number of decimal places
88-
//! in floating-point types:
216+
//! While these:
89217
//!
90218
//! ```
91-
//! let formatted_number = format!("{:.*}", 2, 1.234567);
219+
//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
220+
//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
221+
//! println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
222+
//! ```
92223
//!
93-
//! assert_eq!("1.23", formatted_number)
224+
//! print two significantly different things:
225+
//!
226+
//! ```text
227+
//! Hello, `1234.560` has 3 fractional digits
228+
//! Hello, `123` has 3 characters
229+
//! Hello, ` 123` has 3 right-aligned characters
94230
//! ```
95231
//!
96-
//! If this syntax is used, then the number of characters to print precedes the
97-
//! actual object being formatted, and the number of characters must have the
98-
//! type [`usize`].
232+
//! # Escaping
233+
//!
234+
//! The literal characters `{` and `}` may be included in a string by preceding
235+
//! them with the same character. For example, the `{` character is escaped with
236+
//! `{{` and the `}` character is escaped with `}}`.
237+
//!
238+
//! # Syntax
239+
//!
240+
//! To summarize, you can find the full grammar of format strings.
241+
//! The syntax for the formatting language used is drawn from other languages,
242+
//! so it should not be too alien. Arguments are formatted with Python-like
243+
//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like
244+
//! `%`. The actual grammar for the formatting syntax is:
245+
//!
246+
//! ```text
247+
//! format_string := <text> [ maybe-format <text> ] *
248+
//! maybe-format := '{' '{' | '}' '}' | <format>
249+
//! format := '{' [ argument ] [ ':' format_spec ] '}'
250+
//! argument := integer | identifier
251+
//!
252+
//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
253+
//! fill := character
254+
//! align := '<' | '^' | '>'
255+
//! sign := '+' | '-'
256+
//! width := count
257+
//! precision := count | '*'
258+
//! type := identifier | '?' | ''
259+
//! count := parameter | integer
260+
//! parameter := argument '$'
261+
//! ```
99262
//!
100-
//! ## Formatting traits
263+
//! # Formatting traits
101264
//!
102265
//! When requesting that an argument be formatted with a particular type, you
103266
//! are actually requesting that an argument ascribes to a particular trait.
@@ -220,7 +383,7 @@
220383
//! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\"");
221384
//! ```
222385
//!
223-
//! ## Related macros
386+
//! # Related macros
224387
//!
225388
//! There are a number of related macros in the [`format!`] family. The ones that
226389
//! are currently implemented are:
@@ -300,185 +463,6 @@
300463
//! it would internally pass around this structure until it has been determined
301464
//! where output should go to.
302465
//!
303-
//! # Syntax
304-
//!
305-
//! The syntax for the formatting language used is drawn from other languages,
306-
//! so it should not be too alien. Arguments are formatted with Python-like
307-
//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like
308-
//! `%`. The actual grammar for the formatting syntax is:
309-
//!
310-
//! ```text
311-
//! format_string := <text> [ maybe-format <text> ] *
312-
//! maybe-format := '{' '{' | '}' '}' | <format>
313-
//! format := '{' [ argument ] [ ':' format_spec ] '}'
314-
//! argument := integer | identifier
315-
//!
316-
//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
317-
//! fill := character
318-
//! align := '<' | '^' | '>'
319-
//! sign := '+' | '-'
320-
//! width := count
321-
//! precision := count | '*'
322-
//! type := identifier | '?' | ''
323-
//! count := parameter | integer
324-
//! parameter := argument '$'
325-
//! ```
326-
//!
327-
//! # Formatting Parameters
328-
//!
329-
//! Each argument being formatted can be transformed by a number of formatting
330-
//! parameters (corresponding to `format_spec` in the syntax above). These
331-
//! parameters affect the string representation of what's being formatted.
332-
//!
333-
//! ## Fill/Alignment
334-
//!
335-
//! The fill character is provided normally in conjunction with the
336-
//! [`width`](#width)
337-
//! parameter. This indicates that if the value being formatted is smaller than
338-
//! `width` some extra characters will be printed around it. The extra
339-
//! characters are specified by `fill`, and the alignment can be one of the
340-
//! following options:
341-
//!
342-
//! * `<` - the argument is left-aligned in `width` columns
343-
//! * `^` - the argument is center-aligned in `width` columns
344-
//! * `>` - the argument is right-aligned in `width` columns
345-
//!
346-
//! Note that alignment may not be implemented by some types. In particular, it
347-
//! is not generally implemented for the `Debug` trait. A good way to ensure
348-
//! padding is applied is to format your input, then use this resulting string
349-
//! to pad your output.
350-
//!
351-
//! ## Sign/`#`/`0`
352-
//!
353-
//! These can all be interpreted as flags for a particular formatter.
354-
//!
355-
//! * `+` - This is intended for numeric types and indicates that the sign
356-
//! should always be printed. Positive signs are never printed by
357-
//! default, and the negative sign is only printed by default for the
358-
//! `Signed` trait. This flag indicates that the correct sign (`+` or `-`)
359-
//! should always be printed.
360-
//! * `-` - Currently not used
361-
//! * `#` - This flag is indicates that the "alternate" form of printing should
362-
//! be used. The alternate forms are:
363-
//! * `#?` - pretty-print the [`Debug`] formatting
364-
//! * `#x` - precedes the argument with a `0x`
365-
//! * `#X` - precedes the argument with a `0x`
366-
//! * `#b` - precedes the argument with a `0b`
367-
//! * `#o` - precedes the argument with a `0o`
368-
//! * `0` - This is used to indicate for integer formats that the padding should
369-
//! both be done with a `0` character as well as be sign-aware. A format
370-
//! like `{:08}` would yield `00000001` for the integer `1`, while the
371-
//! same format would yield `-0000001` for the integer `-1`. Notice that
372-
//! the negative version has one fewer zero than the positive version.
373-
//! Note that padding zeroes are always placed after the sign (if any)
374-
//! and before the digits. When used together with the `#` flag, a similar
375-
//! rule applies: padding zeroes are inserted after the prefix but before
376-
//! the digits.
377-
//!
378-
//! ## Width
379-
//!
380-
//! This is a parameter for the "minimum width" that the format should take up.
381-
//! If the value's string does not fill up this many characters, then the
382-
//! padding specified by fill/alignment will be used to take up the required
383-
//! space.
384-
//!
385-
//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
386-
//! left-aligned. The
387-
//! defaults for numeric formatters is also a space but with right-alignment. If
388-
//! the `0` flag is specified for numerics, then the implicit fill character is
389-
//! `0`.
390-
//!
391-
//! The value for the width can also be provided as a [`usize`] in the list of
392-
//! parameters by using the dollar syntax indicating that the second argument is
393-
//! a [`usize`] specifying the width, for example:
394-
//!
395-
//! ```
396-
//! // All of these print "Hello x !"
397-
//! println!("Hello {:5}!", "x");
398-
//! println!("Hello {:1$}!", "x", 5);
399-
//! println!("Hello {1:0$}!", 5, "x");
400-
//! println!("Hello {:width$}!", "x", width = 5);
401-
//! ```
402-
//!
403-
//! Referring to an argument with the dollar syntax does not affect the "next
404-
//! argument" counter, so it's usually a good idea to refer to arguments by
405-
//! position, or use named arguments.
406-
//!
407-
//! ## Precision
408-
//!
409-
//! For non-numeric types, this can be considered a "maximum width". If the resulting string is
410-
//! longer than this width, then it is truncated down to this many characters and that truncated
411-
//! value is emitted with proper `fill`, `alignment` and `width` if those parameters are set.
412-
//!
413-
//! For integral types, this is ignored.
414-
//!
415-
//! For floating-point types, this indicates how many digits after the decimal point should be
416-
//! printed.
417-
//!
418-
//! There are three possible ways to specify the desired `precision`:
419-
//!
420-
//! 1. An integer `.N`:
421-
//!
422-
//! the integer `N` itself is the precision.
423-
//!
424-
//! 2. An integer or name followed by dollar sign `.N$`:
425-
//!
426-
//! use format *argument* `N` (which must be a `usize`) as the precision.
427-
//!
428-
//! 3. An asterisk `.*`:
429-
//!
430-
//! `.*` means that this `{...}` is associated with *two* format inputs rather than one: the
431-
//! first input holds the `usize` precision, and the second holds the value to print. Note that
432-
//! in this case, if one uses the format string `{<arg>:<spec>.*}`, then the `<arg>` part refers
433-
//! to the *value* to print, and the `precision` must come in the input preceding `<arg>`.
434-
//!
435-
//! For example, the following calls all print the same thing `Hello x is 0.01000`:
436-
//!
437-
//! ```
438-
//! // Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)}
439-
//! println!("Hello {0} is {1:.5}", "x", 0.01);
440-
//!
441-
//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)}
442-
//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
443-
//!
444-
//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)}
445-
//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
446-
//!
447-
//! // Hello {next arg ("x")} is {second of next two args (0.01) with precision
448-
//! // specified in first of next two args (5)}
449-
//! println!("Hello {} is {:.*}", "x", 5, 0.01);
450-
//!
451-
//! // Hello {next arg ("x")} is {arg 2 (0.01) with precision
452-
//! // specified in its predecessor (5)}
453-
//! println!("Hello {} is {2:.*}", "x", 5, 0.01);
454-
//!
455-
//! // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified
456-
//! // in arg "prec" (5)}
457-
//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
458-
//! ```
459-
//!
460-
//! While these:
461-
//!
462-
//! ```
463-
//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
464-
//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
465-
//! println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
466-
//! ```
467-
//!
468-
//! print two significantly different things:
469-
//!
470-
//! ```text
471-
//! Hello, `1234.560` has 3 fractional digits
472-
//! Hello, `123` has 3 characters
473-
//! Hello, ` 123` has 3 right-aligned characters
474-
//! ```
475-
//!
476-
//! # Escaping
477-
//!
478-
//! The literal characters `{` and `}` may be included in a string by preceding
479-
//! them with the same character. For example, the `{` character is escaped with
480-
//! `{{` and the `}` character is escaped with `}}`.
481-
//!
482466
//! [`usize`]: ../../std/primitive.usize.html
483467
//! [`isize`]: ../../std/primitive.isize.html
484468
//! [`i8`]: ../../std/primitive.i8.html

0 commit comments

Comments
 (0)