custom-display 0.1.0

A trait for implementing custom formatting logic for types
Documentation
// SPDX-FileCopyrightText: 2026 Marissa (cuddle puddle) <dev@princess.lgbt>
//
// SPDX-License-Identifier: MPL-2.0

/**
 * Asserts that [`CustomDisplay::width_in_chars()`] returns the number of
 * characters that [`CustomDisplay::fmt()`] writes.
 *
 * The macro places a reference to an [`AssertConsistentWidth`] helper made of
 * the [`CustomDisplay`] and value as the first format arg immediately
 * following the format string, and places all provided format args immediately
 * after it.
 *
 * # Usage Requirements
 *
 * The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
 * NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
 * "OPTIONAL" in this document are to be interpreted as described in
 * RFC 2119.
 *
 * The format string MUST consist of exactly one positional parameter, with no
 * text outside of it. As a corrolary, any format args passed to the macro MUST
 * only be used to modify the singular positional parameter (such as [width] or
 * [precision] values).
 *
 * # Examples
 *
 * ```
 * //#[cfg(test)]
 * mod tests {
 *     use std::fmt::Display;
 *     use custom_display::{CustomDisplay, assert_consistent_width};
 *
 *     fn assert_consistent<CD>(display: &CD, value: &CD::Value)
 *     where
 *         CD: CustomDisplay + Display,
 *     {
 *         assert_consistent_width!(display, value, "{}");
 *         assert_consistent_width!(display, value, "{:.6}");
 *         assert_consistent_width!(display, value, "{:.>10.6}");
 *         assert_consistent_width!(display, value, "{0:.1$}", 6);
 *         assert_consistent_width!(display, value, "{:.>width$}", width = 10);
 *     }
 * }
 * ```
 *
 * # Panics
 *
 * Panics if the width computed by [`CustomDisplay::width_in_chars()`] differs
 * from the width of the value written by [`CustomDisplay::fmt()`].
 *
 * [`CustomDisplay::width_in_chars()`]: crate::CustomDisplay::width_in_chars()
 * [`CustomDisplay::fmt()`]: crate::CustomDisplay::fmt()
 * [`AssertConsistentWidth`]: crate::testkit::AssertConsistentWidth
 * [`CustomDisplay`]: crate::CustomDisplay
 * [width]: std::fmt#width
 * [precision]: std::fmt#precision
 */
#[macro_export]
macro_rules! assert_consistent_width {
    // fn assert_consistent_width<CD>(display: &CD, value: &CD::Value, "<fmt string>")
    // where
    //     CD: CustomValue,
    ($display:expr, $value:expr, $fmt:expr) => {
        {
            let helper = $crate::testkit::AssertConsistentWidth::new($display, $value);
            let fmt_args = std::format_args!($fmt, &helper);
            $crate::testkit::assert_consistent_width_impl(&helper, $fmt, fmt_args);
        }
    };
    // fn assert_consistent_width<CD>(display: &CD, value: &CD::Value, "<fmt string>", <fmt args>*)
    // where
    //     CD: CustomValue,
    ($display:expr, $value:expr, $fmt:expr, $($args:tt)*) => {
        {
            let helper = $crate::testkit::AssertConsistentWidth::new($display, $value);
            let fmt_args = std::format_args!($fmt, &helper, $($args)*);
            $crate::testkit::assert_consistent_width_impl(&helper, $fmt, fmt_args);
        }
    };
}