Skip to content

Instantly share code, notes, and snippets.

@spikespaz
Created June 12, 2025 03:07
Show Gist options
  • Save spikespaz/4a1242c54fdbc7af7717d85b297d9175 to your computer and use it in GitHub Desktop.
Save spikespaz/4a1242c54fdbc7af7717d85b297d9175 to your computer and use it in GitHub Desktop.
Rust helper functions for formatting delimited items.
use core::cell::Cell;
use core::fmt::{Display, Formatter, Result};
struct FormatDelimited<'a, T, I, F>
where
I: IntoIterator<Item = T>,
F: Fn(&mut Formatter<'_>, &T) -> Result,
{
inner: Cell<Option<(I, F)>>,
sep: &'a str,
}
impl<T, I, F> Display for FormatDelimited<'_, T, I, F>
where
I: IntoIterator<Item = T>,
F: Fn(&mut Formatter<'_>, &T) -> Result,
{
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
let (iter, format_with) = self.inner.take().unwrap();
let mut iter = iter.into_iter();
if let Some(item) = iter.next() {
(format_with)(f, &item)?;
for item in iter {
f.write_str(self.sep)?;
(format_with)(f, &item)?;
}
}
Ok(())
}
}
#[inline]
pub fn format_delimited<T>(
items: impl IntoIterator<Item = T>,
format_with: impl Fn(&mut Formatter<'_>, &T) -> Result,
sep: &str,
) -> impl Display {
FormatDelimited {
sep,
inner: Cell::new(Some((items, format_with))),
}
}
#[inline]
pub fn display_delimited(items: impl IntoIterator<Item = impl Display>, sep: &str) -> impl Display {
format_delimited(items, |f, item| Display::fmt(item, f), sep)
}
#[cfg(test)]
mod tests {
use super::{display_delimited, format_delimited};
#[test]
fn simple_format_delimited() {
let items = &[1, 2, 3];
let format_with = |f: &mut core::fmt::Formatter<'_>, item: &_| write!(f, "{}", *item * 2);
let formatted = format!("{}", format_delimited(items, format_with, ", "));
assert_eq!(formatted, "2, 4, 6");
}
#[test]
fn simple_display_delimited() {
let items = &["a", "b", "c"];
let formatted = format!("{}", display_delimited(items, ", "));
assert_eq!(formatted, "a, b, c");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment