macro_rules! impl_fmt {
    (
        is_std_type;
        $($rem:tt)*
    ) => { ... };
    (
        $($rem:tt)*
    ) => { ... };
}
Available on crate feature fmt only.
Expand description

For implementing debug or display formatting “manually”.

Generated code

This macro generates:

  • An implementation of the FormatMarker trait for all the impld types,

  • All the listed impls, by repeating the methods (and other associated items) passed to this macro in each of the impls.

Example

Generic type

This demonstrates how you can implement debug formatting for a generic struct.

#![feature(const_mut_refs)]

use const_format::{Error, Formatter, PWrapper, StrWriter};
use const_format::{formatc, impl_fmt, try_};

use std::marker::PhantomData;

pub struct Tupled<T>(u32, T);

// Implements debug formatting for:
// - Tupled<PhantomData<T>>
// - Tupled<bool>
// - Tupled<Option<bool>>
// Repeating the `const_debug_fmt` function definition in each of those 3 impls.
impl_fmt!{
    // The trailing comma is required
    impl[T,] Tupled<PhantomData<T>>
    where[ T: 'static ];

    impl[] Tupled<bool>;
    impl Tupled<Option<bool>>;
     
    pub const fn const_debug_fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
        let mut fmt = fmt.debug_tuple("Tupled");

        // PWrapper implements const_debug_fmt methods for many std types.
        //
        // You can use `call_debug_fmt` for formatting generic std types
        // if this doesn't work
        try_!(PWrapper(self.0).const_debug_fmt(fmt.field()));
        try_!(PWrapper(self.1).const_debug_fmt(fmt.field()));

        fmt.finish()
    }
}

const S_PHANTOM: &str = formatc!("{:?}", Tupled(3, PhantomData::<u32>));
const S_BOOL: &str = formatc!("{:?}", Tupled(5, false));
const S_OPTION: &str = formatc!("{:?}", Tupled(8, Some(true)));

assert_eq!(S_PHANTOM, "Tupled(3, PhantomData)");
assert_eq!(S_BOOL, "Tupled(5, false)");
assert_eq!(S_OPTION, "Tupled(8, Some(true))");

Enum

This demonstrates how you can implement debug formatting for an enum, using this macro purely for implementing the FormatMarker trait.

#![feature(const_mut_refs)]

use const_format::{Error, Formatter, PWrapper, StrWriter};
use const_format::{formatc, impl_fmt, try_};

use std::cmp::Ordering;

pub enum Enum {
    Braced{ord: Ordering},
    Tupled(u32, u32),
    Unit,
}

impl_fmt!{
    impl Enum;
     
    pub const fn const_debug_fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
        match self {
            Self::Braced{ord} => {
                let mut fmt = fmt.debug_struct("Braced");

                // PWrapper implements const_debug_fmt methods for many std types.
                //
                // You can use `call_debug_fmt` for formatting generic std types
                // if this doesn't work
                try_!(PWrapper(*ord).const_debug_fmt(fmt.field("ord")));

                fmt.finish()
            }
            Self::Tupled(f0,f1) => {
                let mut fmt = fmt.debug_tuple("Tupled");

                try_!(PWrapper(*f0).const_debug_fmt(fmt.field()));
                try_!(PWrapper(*f1).const_debug_fmt(fmt.field()));

                fmt.finish()
            }
            Self::Unit => {
                fmt.debug_tuple("Unit").finish()
            }
        }
    }
}

const S_BRACED: &str = formatc!("{:?}", Enum::Braced{ord: Ordering::Greater});
const S_TUPLED: &str = formatc!("{:?}", Enum::Tupled(5, 8));
const S_UNIT: &str = formatc!("{:?}", Enum::Unit);

assert_eq!(S_BRACED, "Braced { ord: Greater }");
assert_eq!(S_TUPLED, "Tupled(5, 8)");
assert_eq!(S_UNIT, "Unit");