# Rust format strings - syntax, width, precision, and traits

> Read Rust format strings from {} through argument capture, width, precision, alignment, escaping, and formatting traits.

HTML: https://rustprint.com/format/format-strings/

A Rust format string mixes literal text with replacement fields. The smallest field is `{}`: it selects the next argument and formats it with `Display`. Add syntax after `:` when you need width, alignment, precision, flags, or a different formatting trait.

**Basic Display formatting**

```rust
assert_eq!(format!("Hello, {}!", "Rust"), "Hello, Rust!");
```

## Rust format string syntax

The official grammar defines a field as an optional argument followed by an optional format specification:

```text title="Format specification grammar"
{ [argument] [ : [[fill]align][sign][#][0][width][.precision][type] ] }
```

The colon only introduces formatting options. With no explicit argument, Rust consumes the next argument. An integer selects a positional argument; an identifier selects a named argument or captures a variable from scope.

**Captured and positional arguments**

```rust
let language = "Rust";
assert_eq!(format!("{language} {0}", "prints"), "Rust prints");
```

## Width

Width is a minimum, not a forced size. Short values are padded; longer values remain intact.

**Static width, fill, and alignment**

```rust
assert_eq!(format!("|{:>8}|", "rust"), "|    rust|");
assert_eq!(format!("|{:*^8}|", "rust"), "|**rust**|");
```

Width can come from another `usize` argument by adding `$`:

**Dynamic width**

```rust
assert_eq!(format!("|{:width$}|", "rust", width = 8), "|rust    |");
```

## Precision

Precision means decimal places for floating-point values and maximum output width for strings. Integral formatters ignore it.

**Floating-point and string precision**

```rust
assert_eq!(format!("{:.2}", 3.14159), "3.14");
assert_eq!(format!("{:.4}", "rustacean"), "rust");
```

## Escaping braces

Double a brace to emit it literally: `{{` becomes `{` and `}}` becomes `}`.

**Escaped braces**

```rust
assert_eq!(format!("{{value}}"), "{value}");
```

## Fix invalid format string errors

Rust parses the format string at compile time. Unmatched braces or malformed replacement fields therefore stop compilation instead of becoming a runtime formatting failure.

**An unmatched opening brace is rejected as an invalid format string**

```rust
fn main() {
    println!("{");
}
```

The failure above is compiled intentionally in CI and must continue to produce an `invalid format string` diagnostic. When you need literal braces in the output, escape them as `{{` and `}}` rather than leaving a single brace in the format text.

## Go deeper

- [Arguments, positions, and captured variables](/format/arguments-and-capture/index.md)
- [Width, alignment, and fill](/format/width-alignment-fill/index.md)
- [Precision](/format/precision/index.md)
- [Binary, octal, hexadecimal, and exponent formatting](/format/number-bases/index.md)
- [Signs and zero padding](/format/signs-and-zero-padding/index.md)
- [Alternate formatting with `#`](/format/alternate-format/index.md)
- [Escaping braces](/format/escaping-braces/index.md)
- [Exact format specifier grammar](/reference/format-specifier-grammar/index.md)

Use the [Rust Format Explorer](/tools/format-string/) to split a field into its grammar tokens.

## Sources

- [std::fmt](https://doc.rust-lang.org/std/fmt/)

## Related RustPrint guides

- [Rust formatting traits - Display, Debug, hex, binary, and more](/reference/formatting-traits/index.md): Map Rust format syntax such as {}, {:?}, {:x}, {:b}, and {:e} to the std::fmt traits Display, Debug, LowerHex, Binary, and LowerExp.
- [Rust format specifier grammar](/reference/format-specifier-grammar/index.md): Read the exact order of fill, alignment, sign, alternate, zero, width, precision, and type in a Rust format specification.
- [Rust output macros: print!, eprintln!, write!, and format!](/output/output-macros/index.md): Choose the right Rust output macro for stdout, stderr, an owned String, or an existing writer, including newline, flushing, and buffering behavior.
