Module powerfmt::smart_display

source ·
Expand description

Definition of SmartDisplay and its related items.

SmartDisplay is a trait that allows authors to provide additional information to both the formatter and other users. This information is provided in the form of a metadata type. The only required piece of metadata is the width of the value. This is before it is passed to the formatter (i.e. it does not include any padding added by the formatter). Other information can be stored in a custom metadata type as needed. This information may be made available to downstream users, but it is not required.

This module contains the SmartDisplay and associated items.

§Example

use std::fmt;

use powerfmt::ext::FormatterExt as _;
use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay};

#[derive(Debug)]
struct User {
    id: usize,
}

// If you try to use `UserMetadata` in the `SmartDisplay` implementation, you will get a
// compiler error about a private type being used publicly. To avoid this, use this attribute to
// declare a private metadata type. You shouldn't need to worry about how this works, but be
// aware that any public fields or methods remain usable by downstream users.
#[smart_display::private_metadata]
struct UserMetadata {
    username: String,
    legal_name: String,
}

// This attribute can be applied to `SmartDisplay` implementations. It will generate an
// implementation of `Display` that delegates to `SmartDisplay`, avoiding the need to write
// boilerplate.
#[smart_display::delegate]
impl SmartDisplay for User {
    type Metadata = UserMetadata;

    fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
        // This could be obtained from a database, for example.
        let legal_name = "John Doe".to_owned();
        let username = "jdoe".to_owned();

        // Note that this must be kept in sync with the implementation of `fmt_with_metadata`.
        let width = smart_display::padded_width_of!(username, " (", legal_name, ")",);

        Metadata::new(
            width,
            self,
            UserMetadata {
                username,
                legal_name,
            },
        )
    }

    // Use the now-generated metadata to format the value. Here we use the `pad_with_width`
    // method to use the alignment and desired width from the formatter.
    fn fmt_with_metadata(
        &self,
        f: &mut fmt::Formatter<'_>,
        metadata: Metadata<Self>,
    ) -> fmt::Result {
        f.pad_with_width(
            metadata.unpadded_width(),
            format_args!("{} ({})", metadata.username, metadata.legal_name),
        )
    }
}

let user = User { id: 42 };
assert_eq!(user.to_string(), "jdoe (John Doe)");
assert_eq!(format!("{user:>20}"), "     jdoe (John Doe)");

Macros§

  • Compute the width of multiple items while optionally declaring the options for each item.

Structs§

Traits§

  • Format trait that allows authors to provide additional information.