use std::cell::Cell; use std::fmt::{self, Display, Formatter}; /// Implements fmt::Display by calling formatter on contents. pub(crate) struct Fmt { contents: Cell>, formatter: F, } impl fmt::Result> Fmt { pub(crate) fn new(t: T, formatter: F) -> Self { Self { contents: Cell::new(Some(t)), formatter, } } } impl fmt::Result> Display for Fmt { /// fmt is single-use only. fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let contents = self.contents.replace(None).expect("only call Fmt::fmt once"); (self.formatter)(contents, f) } } impl, T: Display> Fmt fmt::Result> { /// Formats values with a comma and a space separating them. pub(crate) fn comma_separated(into_iter: I) -> Self { Self::new(into_iter, fmt_comma_separated) } } fn fmt_comma_separated( into_iter: impl IntoIterator, f: &mut Formatter, ) -> fmt::Result { for (i, v) in into_iter.into_iter().enumerate() { if i > 0 { f.write_str(", ")?; } Display::fmt(&v, f)?; } Ok(()) }