itertools/
format.rs

1use std::fmt;
2use std::cell::RefCell;
3
4/// Format all iterator elements lazily, separated by `sep`.
5///
6/// The format value can only be formatted once, after that the iterator is
7/// exhausted.
8///
9/// See [`.format_with()`](crate::Itertools::format_with) for more information.
10#[derive(Clone)]
11pub struct FormatWith<'a, I, F> {
12    sep: &'a str,
13    /// FormatWith uses interior mutability because Display::fmt takes &self.
14    inner: RefCell<Option<(I, F)>>,
15}
16
17/// Format all iterator elements lazily, separated by `sep`.
18///
19/// The format value can only be formatted once, after that the iterator is
20/// exhausted.
21///
22/// See [`.format()`](crate::Itertools::format)
23/// for more information.
24#[derive(Clone)]
25pub struct Format<'a, I> {
26    sep: &'a str,
27    /// Format uses interior mutability because Display::fmt takes &self.
28    inner: RefCell<Option<I>>,
29}
30
31pub fn new_format<I, F>(iter: I, separator: &str, f: F) -> FormatWith<'_, I, F>
32    where I: Iterator,
33          F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result
34{
35    FormatWith {
36        sep: separator,
37        inner: RefCell::new(Some((iter, f))),
38    }
39}
40
41pub fn new_format_default<I>(iter: I, separator: &str) -> Format<'_, I>
42    where I: Iterator,
43{
44    Format {
45        sep: separator,
46        inner: RefCell::new(Some(iter)),
47    }
48}
49
50impl<'a, I, F> fmt::Display for FormatWith<'a, I, F>
51    where I: Iterator,
52          F: FnMut(I::Item, &mut dyn  FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result
53{
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        let (mut iter, mut format) = match self.inner.borrow_mut().take() {
56            Some(t) => t,
57            None => panic!("FormatWith: was already formatted once"),
58        };
59
60        if let Some(fst) = iter.next() {
61            format(fst, &mut |disp: &dyn fmt::Display| disp.fmt(f))?;
62            iter.try_for_each(|elt| {
63                if !self.sep.is_empty() {
64                    f.write_str(self.sep)?;
65                }
66                format(elt, &mut |disp: &dyn fmt::Display| disp.fmt(f))
67            })?;
68        }
69        Ok(())
70    }
71}
72
73impl<'a, I> Format<'a, I>
74    where I: Iterator,
75{
76    fn format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result
77        where F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,
78    {
79        let mut iter = match self.inner.borrow_mut().take() {
80            Some(t) => t,
81            None => panic!("Format: was already formatted once"),
82        };
83
84        if let Some(fst) = iter.next() {
85            cb(&fst, f)?;
86            iter.try_for_each(|elt| {
87                if !self.sep.is_empty() {
88                    f.write_str(self.sep)?;
89                }
90                cb(&elt, f)
91            })?;
92        }
93        Ok(())
94    }
95}
96
97macro_rules! impl_format {
98    ($($fmt_trait:ident)*) => {
99        $(
100            impl<'a, I> fmt::$fmt_trait for Format<'a, I>
101                where I: Iterator,
102                      I::Item: fmt::$fmt_trait,
103            {
104                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105                    self.format(f, fmt::$fmt_trait::fmt)
106                }
107            }
108        )*
109    }
110}
111
112impl_format!{Display Debug
113             UpperExp LowerExp UpperHex LowerHex Octal Binary Pointer}