Created
June 12, 2025 03:07
-
-
Save spikespaz/4a1242c54fdbc7af7717d85b297d9175 to your computer and use it in GitHub Desktop.
Rust helper functions for formatting delimited items.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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