2017-10-06 11:41:04 -03:00
//! Utilities for formatting and printing `String`s.
2015-02-05 21:08:02 -08:00
//!
2017-08-11 13:43:31 +02:00
//! This module contains the runtime support for the [`format!`] syntax extension.
2015-02-05 21:08:02 -08:00
//! This macro is implemented in the compiler to emit calls to this module in
2016-05-12 23:47:14 +02:00
//! order to format arguments at runtime into strings.
2015-02-05 21:08:02 -08:00
//!
2015-03-18 19:00:51 -04:00
//! # Usage
2015-02-05 21:08:02 -08:00
//!
2017-08-11 13:43:31 +02:00
//! The [`format!`] macro is intended to be familiar to those coming from C's
//! `printf`/`fprintf` functions or Python's `str.format` function.
2015-02-05 21:08:02 -08:00
//!
2017-08-11 13:43:31 +02:00
//! Some examples of the [`format!`] extension are:
2015-02-05 21:08:02 -08:00
//!
//! ```
2015-02-17 09:47:49 -05:00
//! format!("Hello"); // => "Hello"
//! format!("Hello, {}!", "world"); // => "Hello, world!"
2015-02-05 21:08:02 -08:00
//! format!("The number is {}", 1); // => "The number is 1"
2015-02-17 09:47:49 -05:00
//! format!("{:?}", (3, 4)); // => "(3, 4)"
2015-02-05 21:08:02 -08:00
//! format!("{value}", value=4); // => "4"
2021-11-01 15:24:39 +01:00
//! let people = "Rustaceans";
//! format!("Hello {people}!"); // => "Hello Rustaceans!"
2015-02-17 09:47:49 -05:00
//! format!("{} {}", 1, 2); // => "1 2"
2016-06-25 01:59:14 +02:00
//! format!("{:04}", 42); // => "0042" with leading zeros
2021-03-22 15:14:24 -04:00
//! format!("{:#?}", (100, 200)); // => "(
//! // 100,
//! // 200,
//! // )"
2015-02-05 21:08:02 -08:00
//! ```
//!
//! From these, you can see that the first argument is a format string. It is
//! required by the compiler for this to be a string literal; it cannot be a
//! variable passed in (in order to perform validity checking). The compiler
//! will then parse the format string and determine if the list of arguments
//! provided is suitable to pass to this format string.
//!
2019-02-09 21:23:30 +00:00
//! To convert a single value to a string, use the [`to_string`] method. This
2018-12-29 02:54:05 -05:00
//! will use the [`Display`] formatting trait.
//!
2015-03-18 19:00:51 -04:00
//! ## Positional parameters
2015-02-05 21:08:02 -08:00
//!
//! Each formatting argument is allowed to specify which value argument it's
//! referencing, and if omitted it is assumed to be "the next argument". For
//! example, the format string `{} {} {}` would take three parameters, and they
//! would be formatted in the same order as they're given. The format string
//! `{2} {1} {0}`, however, would format arguments in reverse order.
//!
//! Things can get a little tricky once you start intermingling the two types of
//! positional specifiers. The "next argument" specifier can be thought of as an
//! iterator over the argument. Each time a "next argument" specifier is seen,
//! the iterator advances. This leads to behavior like this:
//!
2015-03-18 19:00:51 -04:00
//! ```
2015-02-05 21:08:02 -08:00
//! format!("{1} {} {0} {}", 1, 2); // => "2 1 1 2"
//! ```
//!
//! The internal iterator over the argument has not been advanced by the time
//! the first `{}` is seen, so it prints the first argument. Then upon reaching
//! the second `{}`, the iterator has advanced forward to the second argument.
2020-05-06 18:56:25 -04:00
//! Essentially, parameters that explicitly name their argument do not affect
//! parameters that do not name an argument in terms of positional specifiers.
2015-02-05 21:08:02 -08:00
//!
//! A format string is required to use all of its arguments, otherwise it is a
//! compile-time error. You may refer to the same argument more than once in the
2017-02-22 21:18:52 -08:00
//! format string.
2015-02-05 21:08:02 -08:00
//!
2015-03-18 19:00:51 -04:00
//! ## Named parameters
2015-02-05 21:08:02 -08:00
//!
//! Rust itself does not have a Python-like equivalent of named parameters to a
2020-05-06 18:56:25 -04:00
//! function, but the [`format!`] macro is a syntax extension that allows it to
2015-02-05 21:08:02 -08:00
//! leverage named parameters. Named parameters are listed at the end of the
//! argument list and have the syntax:
//!
//! ```text
//! identifier '=' expression
//! ```
//!
2022-02-09 11:26:10 +01:00
//! For example, the following [`format!`] expressions all use named arguments:
2015-02-05 21:08:02 -08:00
//!
//! ```
//! format!("{argument}", argument = "test"); // => "test"
2016-05-12 23:25:33 +02:00
//! format!("{name} {}", 1, name = 2); // => "2 1"
2015-02-05 21:08:02 -08:00
//! format!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b"
//! ```
//!
2021-11-01 15:24:39 +01:00
//! If a named parameter does not appear in the argument list, `format!` will
//! reference a variable with that name in the current scope.
//!
//! ```
//! let argument = 2 + 2;
//! format!("{argument}"); // => "4"
//!
//! fn make_string(a: u32, b: &str) -> String {
//! format!("{b} {a}")
//! }
//! make_string(927, "label"); // => "label 927"
//! ```
//!
2015-07-28 17:53:50 +03:00
//! It is not valid to put positional parameters (those without names) after
2020-05-06 18:56:25 -04:00
//! arguments that have names. Like with positional parameters, it is not
2015-07-28 17:53:50 +03:00
//! valid to provide named parameters that are unused by the format string.
2015-02-05 21:08:02 -08:00
//!
2019-10-12 13:31:58 +02:00
//! # Formatting Parameters
//!
//! Each argument being formatted can be transformed by a number of formatting
2020-07-27 00:00:00 +00:00
//! parameters (corresponding to `format_spec` in [the syntax](#syntax)). These
2019-10-12 13:31:58 +02:00
//! parameters affect the string representation of what's being formatted.
//!
2019-10-17 21:22:46 +02:00
//! ## Width
//!
//! ```
//! // All of these print "Hello x !"
//! println!("Hello {:5}!", "x");
//! println!("Hello {:1$}!", "x", 5);
//! println!("Hello {1:0$}!", 5, "x");
//! println!("Hello {:width$}!", "x", width = 5);
2021-11-01 15:24:39 +01:00
//! let width = 5;
//! println!("Hello {:width$}!", "x");
2019-10-17 21:22:46 +02:00
//! ```
//!
//! This is a parameter for 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 (see below).
//!
//! The value for the width can also be provided as a [`usize`] in the list of
//! parameters by adding a postfix `$`, indicating that the second argument is
//! a [`usize`] specifying the width.
//!
//! Referring to an argument with the dollar syntax does not affect the "next
//! argument" counter, so it's usually a good idea to refer to arguments by
//! position, or use named arguments.
//!
2019-10-12 13:31:58 +02:00
//! ## Fill/Alignment
//!
2019-10-17 21:22:46 +02:00
//! ```
//! assert_eq!(format!("Hello {:<5}!", "x"), "Hello x !");
//! assert_eq!(format!("Hello {:-<5}!", "x"), "Hello x----!");
//! assert_eq!(format!("Hello {:^5}!", "x"), "Hello x !");
//! assert_eq!(format!("Hello {:>5}!", "x"), "Hello x!");
//! ```
//!
//! The optional fill character and alignment is provided normally in conjunction with the
//! [`width`](#width) parameter. It must be defined before `width`, right after the `:`.
//! This indicates that if the value being formatted is smaller than
//! `width` some extra characters will be printed around it.
//! Filling comes in the following variants for different alignments:
2019-10-12 13:31:58 +02:00
//!
2019-10-17 21:22:46 +02:00
//! * `[fill]<` - the argument is left-aligned in `width` columns
//! * `[fill]^` - the argument is center-aligned in `width` columns
//! * `[fill]>` - the argument is right-aligned in `width` columns
//!
//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
//! left-aligned. The
2020-05-06 18:58:45 -04:00
//! default for numeric formatters is also a space character but with right-alignment. If
2019-10-17 21:22:46 +02:00
//! the `0` flag (see below) is specified for numerics, then the implicit fill character is
//! `0`.
2019-10-12 13:31:58 +02:00
//!
2021-07-23 19:14:28 -04:00
//! Note that alignment might not be implemented by some types. In particular, it
2019-10-12 13:31:58 +02:00
//! is not generally implemented for the `Debug` trait. A good way to ensure
2019-10-17 23:00:46 +02:00
//! padding is applied is to format your input, then pad this resulting string
//! to obtain your output:
//!
//! ```
//! println!("Hello {:^15}!", format!("{:?}", Some("hi"))); // => "Hello Some("hi") !"
//! ```
2019-10-12 13:31:58 +02:00
//!
//! ## Sign/`#`/`0`
//!
2019-10-17 21:22:46 +02:00
//! ```
//! assert_eq!(format!("Hello {:+}!", 5), "Hello +5!");
//! assert_eq!(format!("{:#x}!", 27), "0x1b!");
//! assert_eq!(format!("Hello {:05}!", 5), "Hello 00005!");
//! assert_eq!(format!("Hello {:05}!", -5), "Hello -0005!");
//! assert_eq!(format!("{:#010x}!", 27), "0x0000001b!");
//! ```
//!
//! These are all flags altering the behavior of the formatter.
2019-10-12 13:31:58 +02:00
//!
//! * `+` - This is intended for numeric types and indicates that the sign
//! should always be printed. Positive signs are never printed by
2020-10-31 17:21:23 -07:00
//! default, and the negative sign is only printed by default for signed values.
//! This flag indicates that the correct sign (`+` or `-`) should always be printed.
2019-10-12 13:31:58 +02:00
//! * `-` - Currently not used
2020-05-06 18:59:52 -04:00
//! * `#` - This flag indicates that the "alternate" form of printing should
2019-10-12 13:31:58 +02:00
//! be used. The alternate forms are:
2021-03-22 17:09:11 -04:00
//! * `#?` - pretty-print the [`Debug`] formatting (adds linebreaks and indentation)
2019-10-12 13:31:58 +02:00
//! * `#x` - precedes the argument with a `0x`
//! * `#X` - precedes the argument with a `0x`
//! * `#b` - precedes the argument with a `0b`
//! * `#o` - precedes the argument with a `0o`
2019-10-17 21:22:46 +02:00
//! * `0` - This is used to indicate for integer formats that the padding to `width` should
2019-10-12 13:31:58 +02:00
//! both be done with a `0` character as well as be sign-aware. A format
//! like `{:08}` would yield `00000001` for the integer `1`, while the
//! same format would yield `-0000001` for the integer `-1`. Notice that
//! the negative version has one fewer zero than the positive version.
2020-05-06 19:00:15 -04:00
//! Note that padding zeros are always placed after the sign (if any)
2019-10-12 13:31:58 +02:00
//! and before the digits. When used together with the `#` flag, a similar
2020-05-06 19:00:15 -04:00
//! rule applies: padding zeros are inserted after the prefix but before
2019-10-17 21:22:46 +02:00
//! the digits. The prefix is included in the total width.
2019-10-12 13:31:58 +02:00
//!
//! ## Precision
//!
//! For non-numeric types, this can be considered a "maximum width". If the resulting string is
//! longer than this width, then it is truncated down to this many characters and that truncated
//! value is emitted with proper `fill`, `alignment` and `width` if those parameters are set.
//!
//! For integral types, this is ignored.
//!
//! For floating-point types, this indicates how many digits after the decimal point should be
//! printed.
//!
//! There are three possible ways to specify the desired `precision`:
//!
//! 1. An integer `.N`:
//!
//! the integer `N` itself is the precision.
//!
//! 2. An integer or name followed by dollar sign `.N$`:
//!
//! use format *argument* `N` (which must be a `usize`) as the precision.
//!
//! 3. An asterisk `.*`:
//!
2022-04-30 02:38:22 +02:00
//! `.*` means that this `{...}` is associated with *two* format inputs rather than one:
//! - If a format string in the fashion of `{:<spec>.*}` is used, then the first input holds
//! the `usize` precision, and the second holds the value to print.
//! - If a format string in the fashion of `{<arg>:<spec>.*}` is used, then the `<arg>` part
//! refers to the value to print, and the `precision` is taken like it was specified with an
//! omitted positional parameter (`{}` instead of `{<arg>:}`).
2019-10-12 13:31:58 +02:00
//!
//! For example, the following calls all print the same thing `Hello x is 0.01000`:
//!
//! ```
//! // Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)}
//! println!("Hello {0} is {1:.5}", "x", 0.01);
//!
//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)}
//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
//!
//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)}
//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
//!
2022-04-30 02:39:27 +02:00
//! // Hello {next arg -> arg 0 ("x")} is {second of next two args -> arg 2 (0.01) with precision
//! // specified in first of next two args -> arg 1 (5)}
2019-10-12 13:31:58 +02:00
//! println!("Hello {} is {:.*}", "x", 5, 0.01);
//!
2022-04-30 02:38:22 +02:00
//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision
2022-04-30 02:39:27 +02:00
//! // specified in next arg -> arg 0 (5)}
2022-04-30 02:38:22 +02:00
//! println!("Hello {1} is {2:.*}", 5, "x", 0.01);
//!
2022-04-30 02:39:27 +02:00
//! // Hello {next arg -> arg 0 ("x")} is {arg 2 (0.01) with precision
//! // specified in next arg -> arg 1 (5)}
2019-10-12 13:31:58 +02:00
//! println!("Hello {} is {2:.*}", "x", 5, 0.01);
//!
2022-04-30 02:39:27 +02:00
//! // Hello {next arg -> arg 0 ("x")} is {arg "number" (0.01) with precision specified
2019-10-12 13:31:58 +02:00
//! // in arg "prec" (5)}
//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
//! ```
//!
//! While these:
//!
//! ```
//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
//! println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
//! ```
//!
2020-08-11 22:33:11 +02:00
//! print three significantly different things:
2019-10-12 13:31:58 +02:00
//!
//! ```text
//! Hello, `1234.560` has 3 fractional digits
//! Hello, `123` has 3 characters
//! Hello, ` 123` has 3 right-aligned characters
//! ```
//!
2020-03-09 12:31:33 -04:00
//! ## Localization
//!
//! In some programming languages, the behavior of string formatting functions
//! depends on the operating system's locale setting. The format functions
2020-05-06 19:00:40 -04:00
//! provided by Rust's standard library do not have any concept of locale and
2020-03-09 12:31:33 -04:00
//! will produce the same results on all systems regardless of user
//! configuration.
//!
//! For example, the following code will always print `1.5` even if the system
//! locale uses a decimal separator other than a dot.
//!
//! ```
//! println!("The value is {}", 1.5);
//! ```
//!
2019-10-12 13:31:58 +02:00
//! # Escaping
//!
//! The literal characters `{` and `}` may be included in a string by preceding
//! them with the same character. For example, the `{` character is escaped with
//! `{{` and the `}` character is escaped with `}}`.
//!
2019-10-17 21:22:46 +02:00
//! ```
//! assert_eq!(format!("Hello {{}}"), "Hello {}");
//! assert_eq!(format!("{{ Hello"), "{ Hello");
//! ```
//!
2019-10-12 13:31:58 +02:00
//! # Syntax
//!
2019-10-17 21:22:46 +02:00
//! To summarize, here you can find the full grammar of format strings.
2019-10-12 13:31:58 +02:00
//! The syntax for the formatting language used is drawn from other languages,
//! so it should not be too alien. Arguments are formatted with Python-like
//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like
//! `%`. The actual grammar for the formatting syntax is:
//!
//! ```text
2021-01-01 22:53:34 +01:00
//! format_string := text [ maybe_format text ] *
//! maybe_format := '{' '{' | '}' '}' | format
2022-04-30 02:39:59 +02:00
//! format := '{' [ argument ] [ ':' format_spec ] [ ws ] * '}'
2019-10-12 13:31:58 +02:00
//! argument := integer | identifier
//!
2021-01-01 22:53:34 +01:00
//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision]type
2019-10-12 13:31:58 +02:00
//! fill := character
//! align := '<' | '^' | '>'
//! sign := '+' | '-'
//! width := count
//! precision := count | '*'
2021-01-01 22:53:34 +01:00
//! type := '' | '?' | 'x?' | 'X?' | identifier
2019-10-12 13:31:58 +02:00
//! count := parameter | integer
//! parameter := argument '$'
//! ```
2022-04-30 02:39:59 +02:00
//! In the above grammar,
//! - `text` must not contain any `'{'` or `'}'` characters,
//! - `ws` is any character for which [`char::is_whitespace`] returns `true`, has no semantic
//! meaning and is completely optional,
//! - `integer` is a decimal integer that may contain leading zeroes and
//! - `identifier` is an `IDENTIFIER_OR_KEYWORD` (not an `IDENTIFIER`) as defined by the [Rust language reference](https://doc.rust-lang.org/reference/identifiers.html).
2019-10-12 13:31:58 +02:00
//!
//! # Formatting traits
2015-02-05 21:08:02 -08:00
//!
//! When requesting that an argument be formatted with a particular type, you
//! are actually requesting that an argument ascribes to a particular trait.
2017-08-11 13:43:31 +02:00
//! This allows multiple actual types to be formatted via `{:x}` (like [`i8`] as
2019-02-09 21:23:30 +00:00
//! well as [`isize`]). The current mapping of types to traits is:
2015-02-05 21:08:02 -08:00
//!
2017-08-11 13:43:31 +02:00
//! * *nothing* ⇒ [`Display`]
//! * `?` ⇒ [`Debug`]
2018-03-13 14:08:15 +01:00
//! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers
2018-03-19 07:37:59 +01:00
//! * `X?` ⇒ [`Debug`] with upper-case hexadecimal integers
2020-11-07 12:22:24 -08:00
//! * `o` ⇒ [`Octal`]
//! * `x` ⇒ [`LowerHex`]
//! * `X` ⇒ [`UpperHex`]
//! * `p` ⇒ [`Pointer`]
2017-08-11 13:43:31 +02:00
//! * `b` ⇒ [`Binary`]
2020-11-07 12:22:24 -08:00
//! * `e` ⇒ [`LowerExp`]
//! * `E` ⇒ [`UpperExp`]
2015-02-05 21:08:02 -08:00
//!
//! What this means is that any type of argument which implements the
2017-08-11 13:43:31 +02:00
//! [`fmt::Binary`][`Binary`] trait can then be formatted with `{:b}`. Implementations
2015-02-05 21:08:02 -08:00
//! are provided for these traits for a number of primitive types by the
//! standard library as well. If no format is specified (as in `{}` or `{:6}`),
2017-08-11 13:43:31 +02:00
//! then the format trait used is the [`Display`] trait.
2015-02-05 21:08:02 -08:00
//!
//! When implementing a format trait for your own type, you will have to
//! implement a method of the signature:
//!
2015-03-18 19:00:51 -04:00
//! ```
2015-11-03 14:49:33 +00:00
//! # #![allow(dead_code)]
2015-02-05 21:08:02 -08:00
//! # use std::fmt;
//! # struct Foo; // our custom type
//! # impl fmt::Display for Foo {
//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//! # write!(f, "testing, testing")
//! # } }
//! ```
//!
//! Your type will be passed as `self` by-reference, and then the function
2022-04-30 02:40:39 +02:00
//! should emit output into the Formatter `f` which implements `fmt::Write`. It is up to each
//! format trait implementation to correctly adhere to the requested formatting parameters.
//! The values of these parameters can be accessed with methods of the
2017-08-11 13:43:31 +02:00
//! [`Formatter`] struct. In order to help with this, the [`Formatter`] struct also
2015-02-05 21:08:02 -08:00
//! provides some helper methods.
//!
2017-08-11 13:43:31 +02:00
//! Additionally, the return value of this function is [`fmt::Result`] which is a
Apply 16 commits (squashed)
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync}
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::string
----------
Fix spacing for links inside code blocks in alloc::vec
----------
Fix spacing for links inside code blocks in core::option
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in core::result
----------
Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll}
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path}
----------
Fix spacing for links inside code blocks in std::{collections, time}
----------
Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str}
----------
Fix spacing for links inside code blocks, and improve link tooltips in std::ffi
----------
Fix spacing for links inside code blocks, and improve a few link tooltips
in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}}
----------
Fix typo in link to `into` for `OsString` docs
----------
Remove tooltips that will probably become redundant in the future
----------
Apply suggestions from code review
Replacing `…std/primitive.reference.html` paths with just `reference`
Co-authored-by: Joshua Nelson <github@jyn.dev>
----------
Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
//! type alias of <code>[Result]<(), [std::fmt::Error]></code>. Formatting implementations
2019-12-26 05:04:46 -08:00
//! should ensure that they propagate errors from the [`Formatter`] (e.g., when
2018-10-13 21:20:36 +02:00
//! calling [`write!`]). However, they should never return errors spuriously. That
2016-08-23 10:47:28 -04:00
//! is, a formatting implementation must and may only return an error if the
2017-08-11 13:43:31 +02:00
//! passed-in [`Formatter`] returns an error. This is because, contrary to what
2016-08-23 10:47:28 -04:00
//! the function signature might suggest, string formatting is an infallible
//! operation. This function only returns a result because writing to the
//! underlying stream might fail and it must provide a way to propagate the fact
//! that an error has occurred back up the stack.
2015-02-05 21:08:02 -08:00
//!
//! An example of implementing the formatting traits would look
//! like:
//!
2015-03-18 19:00:51 -04:00
//! ```
2015-02-05 21:08:02 -08:00
//! use std::fmt;
//!
//! #[derive(Debug)]
//! struct Vector2D {
2015-02-12 16:45:07 -05:00
//! x: isize,
//! y: isize,
2015-02-05 21:08:02 -08:00
//! }
//!
//! impl fmt::Display for Vector2D {
//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2015-02-14 12:56:32 +13:00
//! // The `f` value implements the `Write` trait, which is what the
2015-02-05 21:08:02 -08:00
//! // write! macro is expecting. Note that this formatting ignores the
//! // various flags provided to format strings.
//! write!(f, "({}, {})", self.x, self.y)
//! }
//! }
//!
//! // Different traits allow different forms of output of a type. The meaning
//! // of this format is to print the magnitude of a vector.
//! impl fmt::Binary for Vector2D {
//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//! let magnitude = (self.x * self.x + self.y * self.y) as f64;
//! let magnitude = magnitude.sqrt();
//!
//! // Respect the formatting flags by using the helper method
2015-04-17 23:45:55 -07:00
//! // `pad_integral` on the Formatter object. See the method
//! // documentation for details, and the function `pad` can be used
//! // to pad strings.
2015-02-05 21:08:02 -08:00
//! let decimals = f.precision().unwrap_or(3);
2015-04-17 23:45:55 -07:00
//! let string = format!("{:.*}", decimals, magnitude);
2015-03-07 22:30:12 -08:00
//! f.pad_integral(true, "", &string)
2015-02-05 21:08:02 -08:00
//! }
//! }
//!
//! fn main() {
//! let myvector = Vector2D { x: 3, y: 4 };
//!
2022-02-12 23:16:17 +04:00
//! println!("{myvector}"); // => "(3, 4)"
//! println!("{myvector:?}"); // => "Vector2D {x: 3, y:4}"
//! println!("{myvector:10.3b}"); // => " 5.000"
2015-02-05 21:08:02 -08:00
//! }
//! ```
//!
2015-09-28 22:23:16 -04:00
//! ### `fmt::Display` vs `fmt::Debug`
2015-02-05 21:08:02 -08:00
//!
//! These two formatting traits have distinct purposes:
//!
2017-08-11 13:46:12 +02:00
//! - [`fmt::Display`][`Display`] implementations assert that the type can be faithfully
2015-02-05 21:08:02 -08:00
//! represented as a UTF-8 string at all times. It is **not** expected that
2017-08-18 16:32:38 +02:00
//! all types implement the [`Display`] trait.
2017-08-11 13:43:31 +02:00
//! - [`fmt::Debug`][`Debug`] implementations should be implemented for **all** public types.
2015-02-05 21:08:02 -08:00
//! Output will typically represent the internal state as faithfully as possible.
2017-08-11 13:43:31 +02:00
//! The purpose of the [`Debug`] trait is to facilitate debugging Rust code. In
2015-02-05 21:08:02 -08:00
//! most cases, using `#[derive(Debug)]` is sufficient and recommended.
//!
//! Some examples of the output from both traits:
//!
//! ```
2015-03-03 10:42:26 +02:00
//! assert_eq!(format!("{} {:?}", 3, 4), "3 4");
2015-02-05 21:08:02 -08:00
//! assert_eq!(format!("{} {:?}", 'a', 'b'), "a 'b'");
//! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\"");
//! ```
//!
2019-10-12 13:31:58 +02:00
//! # Related macros
2015-02-05 21:08:02 -08:00
//!
2017-08-11 13:43:31 +02:00
//! There are a number of related macros in the [`format!`] family. The ones that
2015-02-05 21:08:02 -08:00
//! are currently implemented are:
//!
2017-06-20 15:15:16 +08:00
//! ```ignore (only-for-syntax-highlight)
2015-02-05 21:08:02 -08:00
//! format! // described above
2022-04-30 02:41:32 +02:00
//! write! // first argument is either a &mut io::Write or a &mut fmt::Write, the destination
2015-02-05 21:08:02 -08:00
//! writeln! // same as write but appends a newline
//! print! // the format string is printed to the standard output
//! println! // same as print but appends a newline
2017-11-22 20:44:05 -08:00
//! eprint! // the format string is printed to the standard error
//! eprintln! // same as eprint but appends a newline
2015-02-05 21:08:02 -08:00
//! format_args! // described below.
//! ```
//!
2015-03-18 19:00:51 -04:00
//! ### `write!`
2015-02-05 21:08:02 -08:00
//!
2022-04-30 02:41:32 +02:00
//! [`write!`] and [`writeln!`] are two macros which are used to emit the format string
2015-02-05 21:08:02 -08:00
//! to a specified stream. This is used to prevent intermediate allocations of
//! format strings and instead directly write the output. Under the hood, this
2017-08-11 13:43:31 +02:00
//! function is actually invoking the [`write_fmt`] function defined on the
2022-04-30 02:41:32 +02:00
//! [`std::io::Write`] and the [`std::fmt::Write`] trait. Example usage is:
2015-02-05 21:08:02 -08:00
//!
2015-03-18 19:00:51 -04:00
//! ```
2015-02-05 21:08:02 -08:00
//! # #![allow(unused_must_use)]
2015-03-17 13:33:26 -07:00
//! use std::io::Write;
2015-02-05 21:08:02 -08:00
//! let mut w = Vec::new();
//! write!(&mut w, "Hello {}!", "world");
//! ```
//!
2015-03-18 19:00:51 -04:00
//! ### `print!`
2015-02-05 21:08:02 -08:00
//!
2017-08-11 13:43:31 +02:00
//! This and [`println!`] emit their output to stdout. Similarly to the [`write!`]
2015-02-05 21:08:02 -08:00
//! macro, the goal of these macros is to avoid intermediate allocations when
//! printing output. Example usage is:
//!
2015-03-18 19:00:51 -04:00
//! ```
2015-02-05 21:08:02 -08:00
//! print!("Hello {}!", "world");
//! println!("I have a newline {}", "character at the end");
//! ```
2017-11-22 20:44:05 -08:00
//! ### `eprint!`
//!
//! The [`eprint!`] and [`eprintln!`] macros are identical to
//! [`print!`] and [`println!`], respectively, except they emit their
//! output to stderr.
2015-02-05 21:08:02 -08:00
//!
2015-03-18 19:00:51 -04:00
//! ### `format_args!`
//!
2022-04-30 02:41:32 +02:00
//! [`format_args!`] is a curious macro used to safely pass around
2015-02-05 21:08:02 -08:00
//! an opaque object describing the format string. This object
//! does not require any heap allocations to create, and it only
//! references information on the stack. Under the hood, all of
//! the related macros are implemented in terms of this. First
//! off, some example usage is:
//!
//! ```
2015-11-03 14:49:33 +00:00
//! # #![allow(unused_must_use)]
2015-02-05 21:08:02 -08:00
//! use std::fmt;
2015-03-17 13:33:26 -07:00
//! use std::io::{self, Write};
2015-02-05 21:08:02 -08:00
//!
2015-03-17 13:33:26 -07:00
//! let mut some_writer = io::stdout();
2015-02-05 21:08:02 -08:00
//! write!(&mut some_writer, "{}", format_args!("print with a {}", "macro"));
//!
//! fn my_fmt_fn(args: fmt::Arguments) {
2015-03-17 13:33:26 -07:00
//! write!(&mut io::stdout(), "{}", args);
2015-02-05 21:08:02 -08:00
//! }
2016-05-14 12:35:02 +02:00
//! my_fmt_fn(format_args!(", or a {} too", "function"));
2015-02-05 21:08:02 -08:00
//! ```
//!
2017-08-11 13:43:31 +02:00
//! The result of the [`format_args!`] macro is a value of type [`fmt::Arguments`].
//! This structure can then be passed to the [`write`] and [`format`] functions
2015-02-05 21:08:02 -08:00
//! inside this module in order to process the format string.
//! The goal of this macro is to even further prevent intermediate allocations
2020-05-06 19:01:27 -04:00
//! when dealing with formatting strings.
2015-02-05 21:08:02 -08:00
//!
//! For example, a logging library could use the standard formatting syntax, but
//! it would internally pass around this structure until it has been determined
//! where output should go to.
//!
Apply 16 commits (squashed)
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync}
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::string
----------
Fix spacing for links inside code blocks in alloc::vec
----------
Fix spacing for links inside code blocks in core::option
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in core::result
----------
Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll}
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path}
----------
Fix spacing for links inside code blocks in std::{collections, time}
----------
Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str}
----------
Fix spacing for links inside code blocks, and improve link tooltips in std::ffi
----------
Fix spacing for links inside code blocks, and improve a few link tooltips
in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}}
----------
Fix typo in link to `into` for `OsString` docs
----------
Remove tooltips that will probably become redundant in the future
----------
Apply suggestions from code review
Replacing `…std/primitive.reference.html` paths with just `reference`
Co-authored-by: Joshua Nelson <github@jyn.dev>
----------
Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
//! [`fmt::Result`]: Result "fmt::Result"
//! [Result]: core::result::Result "std::result::Result"
//! [std::fmt::Error]: Error "fmt::Error"
//! [`write`]: write() "fmt::write"
//! [`to_string`]: crate::string::ToString::to_string "ToString::to_string"
2017-08-11 13:46:12 +02:00
//! [`write_fmt`]: ../../std/io/trait.Write.html#method.write_fmt
//! [`std::io::Write`]: ../../std/io/trait.Write.html
2022-04-30 02:41:32 +02:00
//! [`std::fmt::Write`]: ../../std/fmt/trait.Write.html
Apply 16 commits (squashed)
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync}
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::string
----------
Fix spacing for links inside code blocks in alloc::vec
----------
Fix spacing for links inside code blocks in core::option
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in core::result
----------
Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll}
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path}
----------
Fix spacing for links inside code blocks in std::{collections, time}
----------
Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str}
----------
Fix spacing for links inside code blocks, and improve link tooltips in std::ffi
----------
Fix spacing for links inside code blocks, and improve a few link tooltips
in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}}
----------
Fix typo in link to `into` for `OsString` docs
----------
Remove tooltips that will probably become redundant in the future
----------
Apply suggestions from code review
Replacing `…std/primitive.reference.html` paths with just `reference`
Co-authored-by: Joshua Nelson <github@jyn.dev>
----------
Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
//! [`print!`]: ../../std/macro.print.html "print!"
//! [`println!`]: ../../std/macro.println.html "println!"
//! [`eprint!`]: ../../std/macro.eprint.html "eprint!"
//! [`eprintln!`]: ../../std/macro.eprintln.html "eprintln!"
2022-04-30 02:41:32 +02:00
//! [`format_args!`]: ../../std/macro.format_args.html "format_args!"
Apply 16 commits (squashed)
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync}
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::string
----------
Fix spacing for links inside code blocks in alloc::vec
----------
Fix spacing for links inside code blocks in core::option
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in core::result
----------
Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll}
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path}
----------
Fix spacing for links inside code blocks in std::{collections, time}
----------
Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str}
----------
Fix spacing for links inside code blocks, and improve link tooltips in std::ffi
----------
Fix spacing for links inside code blocks, and improve a few link tooltips
in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}}
----------
Fix typo in link to `into` for `OsString` docs
----------
Remove tooltips that will probably become redundant in the future
----------
Apply suggestions from code review
Replacing `…std/primitive.reference.html` paths with just `reference`
Co-authored-by: Joshua Nelson <github@jyn.dev>
----------
Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
//! [`fmt::Arguments`]: Arguments "fmt::Arguments"
//! [`format`]: format() "fmt::format"
2014-09-07 14:57:26 -07:00
2015-02-09 16:33:19 -08:00
#![ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2014-09-07 14:57:26 -07:00
2019-12-21 13:16:18 +02:00
#[ unstable(feature = " fmt_internals " , issue = " none " ) ]
2015-11-16 21:01:06 +03:00
pub use core ::fmt ::rt ;
2019-11-29 19:30:49 -08:00
#[ stable(feature = " fmt_flags_align " , since = " 1.28.0 " ) ]
pub use core ::fmt ::Alignment ;
2015-11-16 19:54:28 +03:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2019-11-29 19:30:49 -08:00
pub use core ::fmt ::Error ;
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
pub use core ::fmt ::{ write , ArgumentV1 , Arguments } ;
2019-02-03 08:27:44 +01:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
pub use core ::fmt ::{ Binary , Octal } ;
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
pub use core ::fmt ::{ Debug , Display } ;
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2019-11-29 19:30:49 -08:00
pub use core ::fmt ::{ DebugList , DebugMap , DebugSet , DebugStruct , DebugTuple } ;
2019-02-03 08:27:44 +01:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2019-11-29 19:30:49 -08:00
pub use core ::fmt ::{ Formatter , Result , Write } ;
2019-02-03 08:27:44 +01:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2019-11-29 19:30:49 -08:00
pub use core ::fmt ::{ LowerExp , UpperExp } ;
2019-02-03 08:27:44 +01:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2019-11-29 19:30:49 -08:00
pub use core ::fmt ::{ LowerHex , Pointer , UpperHex } ;
2014-09-07 14:57:26 -07:00
alloc: Add unstable Cfg feature `no-global_oom_handling`
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[ cfg(not(no_global_oom_handling)) ]
2019-02-02 08:36:45 +01:00
use crate ::string ;
2014-09-07 14:57:26 -07:00
2017-08-11 13:46:12 +02:00
/// The `format` function takes an [`Arguments`] struct and returns the resulting
2017-06-22 20:02:57 +01:00
/// formatted string.
2014-09-07 14:57:26 -07:00
///
2017-08-11 13:46:12 +02:00
/// The [`Arguments`] instance can be created with the [`format_args!`] macro.
2014-09-07 14:57:26 -07:00
///
2015-03-11 21:11:40 -04:00
/// # Examples
2014-09-07 14:57:26 -07:00
///
2016-05-01 14:04:13 +02:00
/// Basic usage:
///
2015-03-12 22:42:38 -04:00
/// ```
2014-09-07 14:57:26 -07:00
/// use std::fmt;
///
/// let s = fmt::format(format_args!("Hello, {}!", "world"));
2016-05-12 23:11:52 +02:00
/// assert_eq!(s, "Hello, world!");
2014-09-07 14:57:26 -07:00
/// ```
2016-05-01 14:04:13 +02:00
///
2017-11-21 15:33:45 +01:00
/// Please note that using [`format!`] might be preferable.
2016-05-01 14:04:13 +02:00
/// Example:
///
/// ```
/// let s = format!("Hello, {}!", "world");
2016-05-12 23:11:52 +02:00
/// assert_eq!(s, "Hello, world!");
2016-05-01 14:04:13 +02:00
/// ```
///
2020-08-20 23:43:46 +02:00
/// [`format_args!`]: core::format_args
/// [`format!`]: crate::format
alloc: Add unstable Cfg feature `no-global_oom_handling`
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[ cfg(not(no_global_oom_handling)) ]
2021-10-14 19:56:53 -04:00
#[ must_use ]
2014-09-07 14:57:26 -07:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2022-05-28 11:01:09 +01:00
#[ inline ]
2019-02-02 12:48:12 +01:00
pub fn format ( args : Arguments < '_ > ) -> string ::String {
2022-05-28 12:08:27 +01:00
fn format_inner ( args : Arguments < '_ > ) -> string ::String {
2022-05-28 11:01:09 +01:00
let capacity = args . estimated_capacity ( ) ;
let mut output = string ::String ::with_capacity ( capacity ) ;
output . write_fmt ( args ) . expect ( " a formatting trait implementation returned an error " ) ;
output
}
2022-05-28 12:08:27 +01:00
args . as_str ( ) . map_or_else ( | | format_inner ( args ) , crate ::borrow ::ToOwned ::to_owned )
2014-09-07 14:57:26 -07:00
}