Skip to main content

SmartFormat

Trait SmartFormat 

Source
pub trait SmartFormat: Display + Sized {
    // Provided methods
    fn display_wrap<P: Display, S: Display>(
        self,
        prefix: P,
        suffix: S,
    ) -> Wrap<Self, P, S> { ... }
    fn display_prefix<P: Display>(self, prefix: P) -> Prefix<Self, P> { ... }
    fn display_suffix<S: Display>(self, suffix: S) -> Suffix<Self, S> { ... }
    fn display_if(self, condition: bool) -> If<Self> { ... }
    fn display_or_if<U: Display>(
        self,
        use_fallback: bool,
        fallback: U,
    ) -> Or<Self, U> { ... }
    fn display_truncate(self, max_chars: usize) -> Truncate<Self> { ... }
    fn display_truncate_with(
        self,
        max_chars: usize,
        tail: &'static str,
    ) -> TruncateWith<Self> { ... }
    fn display_pad_right(self, width: usize, fill: char) -> PadRight<Self> { ... }
    fn display_pad_left(self, width: usize, fill: char) -> PadLeft<Self> { ... }
}
Expand description

Extension trait that adds composable formatting combinators to any Display type.

Every method returns a lightweight wrapper struct that itself implements Display. This means combinators chain without intermediate allocations:

use smart_format::prelude::*;

let output = "hello".display_suffix("!").display_prefix("> ").to_string();
assert_eq!(output, "> hello!");

§Design

Each combinator is a struct wrapping T: Display — a zero-allocation adapter by construction. The pattern is the same one used by iterator adapters: lazy evaluation, composed through trait objects (fmt::Formatter), with no heap allocation until someone explicitly materializes the result (.to_string(), write!, etc.).

Width-sensitive operations (display_truncate, display_pad_left, display_pad_right) count Unicode scalar values (char), not bytes or grapheme clusters. This is a known limitation documented on each method.

Provided Methods§

Source

fn display_wrap<P: Display, S: Display>( self, prefix: P, suffix: S, ) -> Wrap<Self, P, S>

Wrap with a prefix and suffix: prefix + self + suffix.

Source

fn display_prefix<P: Display>(self, prefix: P) -> Prefix<Self, P>

Prepend a prefix: prefix + self.

Source

fn display_suffix<S: Display>(self, suffix: S) -> Suffix<Self, S>

Append a suffix: self + suffix.

Source

fn display_if(self, condition: bool) -> If<Self>

Conditionally display: if condition is true, display self; otherwise write nothing.

Source

fn display_or_if<U: Display>( self, use_fallback: bool, fallback: U, ) -> Or<Self, U>

Conditionally choose: if use_fallback is false, display self; otherwise display fallback.

This uses a bool flag rather than inspecting the inner value for emptiness. Value-inspection-based fallback would require either allocation or a DisplayMeta trait (planned for a future version).

Source

fn display_truncate(self, max_chars: usize) -> Truncate<Self>

Truncate to at most max_chars Unicode scalar values.

If the formatted output is shorter than max_chars, it passes through unchanged. If longer, it is cut at the char boundary before the limit. Output is guaranteed to be <= max_chars characters.

Uses char count, not grapheme clusters or terminal display width.

Source

fn display_truncate_with( self, max_chars: usize, tail: &'static str, ) -> TruncateWith<Self>

Truncate with a tail indicator (e.g., “…”).

max_chars is the total output budget including the tail. Inner content is truncated at max_chars - tail.len_in_chars() chars, then the tail is appended. If the inner content fits within the budget, no truncation occurs and the tail is not shown.

Source

fn display_pad_right(self, width: usize, fill: char) -> PadRight<Self>

Right-pad to width characters using fill.

If the formatted output is already >= width characters, no padding is added. Uses char count, not grapheme clusters or terminal display width.

Source

fn display_pad_left(self, width: usize, fill: char) -> PadLeft<Self>

Left-pad to width characters using fill.

If the formatted output is already >= width characters, no padding is added.

§Implementation note

Uses two-pass formatting: first pass counts chars (discarding output), second pass writes padding then content. This is zero-alloc but formats the inner value twice. For the short values where padding typically matters, this cost is negligible.

Assumes Display::fmt is deterministic — non-deterministic implementations (e.g., values including timestamps) may produce incorrect padding width.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§