Skip to content

Commit ab1ae48

Browse files
authoredMay 2, 2022
Rollup merge of #96568 - EliasHolzmann:fmt_doc_fixes, r=joshtriplett
std::fmt: Various fixes and improvements to documentation This PR contains the following changes: - **Added argument index comments to examples for specifying precision** The examples for specifying the precision have comments explaining which argument the specifier is referring to. However, for implicit positional arguments, the examples simply refer to "next arg". To simplify following the comments, "next arg" was supplemented with the actual resulting argument index. - **Fixed documentation for specifying precision via `.*`** The documentation stated that in case of the syntax `{<arg>:<spec>.*}`, "the `<arg>` part refers to the value to print, and the precision must come in the input preceding `<arg>`". This is not correct: the <arg> part does indeed refer to the value to print, but the precision does not come in the input preciding arg, but in the next implicit input (as if specified with {}). Fixes #96413. - **Fix the grammar documentation** According to the grammar documented, the format specifier `{: }` should not be legal because of the whitespace it contains. However, in reality, this is perfectly fine because the actual implementation allows spaces before the closing brace. Fixes #71088. Also, the exact meaning of most of the terminal symbols was not specified, for example the meaning of `identifier`. - **Removed reference to Formatter::buf and other private fields** Formatter::buf is not a public field and therefore isn't very helpful in user- facing documentation. Also, the other public fields of Formatter were removed during stabilization of std::fmt (4af3494) and can only be accessed via getters. - **Improved list of formatting macros** Two improvements: 1. write! can not only receive a `io::Write`, but also a `fmt::Write` as first argument. 2. The description texts now contain links to the actual macros for easier navigation.
2 parents f581354 + f3b86c3 commit ab1ae48

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed
 

‎library/alloc/src/fmt.rs

+31-18
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,12 @@
221221
//!
222222
//! 3. An asterisk `.*`:
223223
//!
224-
//! `.*` means that this `{...}` is associated with *two* format inputs rather than one: the
225-
//! first input holds the `usize` precision, and the second holds the value to print. Note that
226-
//! in this case, if one uses the format string `{<arg>:<spec>.*}`, then the `<arg>` part refers
227-
//! to the *value* to print, and the `precision` must come in the input preceding `<arg>`.
224+
//! `.*` means that this `{...}` is associated with *two* format inputs rather than one:
225+
//! - If a format string in the fashion of `{:<spec>.*}` is used, then the first input holds
226+
//! the `usize` precision, and the second holds the value to print.
227+
//! - If a format string in the fashion of `{<arg>:<spec>.*}` is used, then the `<arg>` part
228+
//! refers to the value to print, and the `precision` is taken like it was specified with an
229+
//! omitted positional parameter (`{}` instead of `{<arg>:}`).
228230
//!
229231
//! For example, the following calls all print the same thing `Hello x is 0.01000`:
230232
//!
@@ -238,15 +240,19 @@
238240
//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)}
239241
//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
240242
//!
241-
//! // Hello {next arg ("x")} is {second of next two args (0.01) with precision
242-
//! // specified in first of next two args (5)}
243+
//! // Hello {next arg -> arg 0 ("x")} is {second of next two args -> arg 2 (0.01) with precision
244+
//! // specified in first of next two args -> arg 1 (5)}
243245
//! println!("Hello {} is {:.*}", "x", 5, 0.01);
244246
//!
245-
//! // Hello {next arg ("x")} is {arg 2 (0.01) with precision
246-
//! // specified in its predecessor (5)}
247+
//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision
248+
//! // specified in next arg -> arg 0 (5)}
249+
//! println!("Hello {1} is {2:.*}", 5, "x", 0.01);
250+
//!
251+
//! // Hello {next arg -> arg 0 ("x")} is {arg 2 (0.01) with precision
252+
//! // specified in next arg -> arg 1 (5)}
247253
//! println!("Hello {} is {2:.*}", "x", 5, 0.01);
248254
//!
249-
//! // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified
255+
//! // Hello {next arg -> arg 0 ("x")} is {arg "number" (0.01) with precision specified
250256
//! // in arg "prec" (5)}
251257
//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
252258
//! ```
@@ -304,7 +310,7 @@
304310
//! ```text
305311
//! format_string := text [ maybe_format text ] *
306312
//! maybe_format := '{' '{' | '}' '}' | format
307-
//! format := '{' [ argument ] [ ':' format_spec ] '}'
313+
//! format := '{' [ argument ] [ ':' format_spec ] [ ws ] * '}'
308314
//! argument := integer | identifier
309315
//!
310316
//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision]type
@@ -317,7 +323,12 @@
317323
//! count := parameter | integer
318324
//! parameter := argument '$'
319325
//! ```
320-
//! In the above grammar, `text` must not contain any `'{'` or `'}'` characters.
326+
//! In the above grammar,
327+
//! - `text` must not contain any `'{'` or `'}'` characters,
328+
//! - `ws` is any character for which [`char::is_whitespace`] returns `true`, has no semantic
329+
//! meaning and is completely optional,
330+
//! - `integer` is a decimal integer that may contain leading zeroes and
331+
//! - `identifier` is an `IDENTIFIER_OR_KEYWORD` (not an `IDENTIFIER`) as defined by the [Rust language reference](https://doc.rust-lang.org/reference/identifiers.html).
321332
//!
322333
//! # Formatting traits
323334
//!
@@ -358,9 +369,9 @@
358369
//! ```
359370
//!
360371
//! Your type will be passed as `self` by-reference, and then the function
361-
//! should emit output into the `f.buf` stream. It is up to each format trait
362-
//! implementation to correctly adhere to the requested formatting parameters.
363-
//! The values of these parameters will be listed in the fields of the
372+
//! should emit output into the Formatter `f` which implements `fmt::Write`. It is up to each
373+
//! format trait implementation to correctly adhere to the requested formatting parameters.
374+
//! The values of these parameters can be accessed with methods of the
364375
//! [`Formatter`] struct. In order to help with this, the [`Formatter`] struct also
365376
//! provides some helper methods.
366377
//!
@@ -449,7 +460,7 @@
449460
//!
450461
//! ```ignore (only-for-syntax-highlight)
451462
//! format! // described above
452-
//! write! // first argument is a &mut io::Write, the destination
463+
//! write! // first argument is either a &mut io::Write or a &mut fmt::Write, the destination
453464
//! writeln! // same as write but appends a newline
454465
//! print! // the format string is printed to the standard output
455466
//! println! // same as print but appends a newline
@@ -460,11 +471,11 @@
460471
//!
461472
//! ### `write!`
462473
//!
463-
//! This and [`writeln!`] are two macros which are used to emit the format string
474+
//! [`write!`] and [`writeln!`] are two macros which are used to emit the format string
464475
//! to a specified stream. This is used to prevent intermediate allocations of
465476
//! format strings and instead directly write the output. Under the hood, this
466477
//! function is actually invoking the [`write_fmt`] function defined on the
467-
//! [`std::io::Write`] trait. Example usage is:
478+
//! [`std::io::Write`] and the [`std::fmt::Write`] trait. Example usage is:
468479
//!
469480
//! ```
470481
//! # #![allow(unused_must_use)]
@@ -491,7 +502,7 @@
491502
//!
492503
//! ### `format_args!`
493504
//!
494-
//! This is a curious macro used to safely pass around
505+
//! [`format_args!`] is a curious macro used to safely pass around
495506
//! an opaque object describing the format string. This object
496507
//! does not require any heap allocations to create, and it only
497508
//! references information on the stack. Under the hood, all of
@@ -529,10 +540,12 @@
529540
//! [`to_string`]: crate::string::ToString::to_string "ToString::to_string"
530541
//! [`write_fmt`]: ../../std/io/trait.Write.html#method.write_fmt
531542
//! [`std::io::Write`]: ../../std/io/trait.Write.html
543+
//! [`std::fmt::Write`]: ../../std/fmt/trait.Write.html
532544
//! [`print!`]: ../../std/macro.print.html "print!"
533545
//! [`println!`]: ../../std/macro.println.html "println!"
534546
//! [`eprint!`]: ../../std/macro.eprint.html "eprint!"
535547
//! [`eprintln!`]: ../../std/macro.eprintln.html "eprintln!"
548+
//! [`format_args!`]: ../../std/macro.format_args.html "format_args!"
536549
//! [`fmt::Arguments`]: Arguments "fmt::Arguments"
537550
//! [`format`]: format() "fmt::format"
538551

0 commit comments

Comments
 (0)