1 use std::fmt;
2 use 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()`](../trait.Itertools.html#method.format_with) for more information.
10 #[derive(Clone)]
11 pub 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()`](../trait.Itertools.html#method.format)
23 /// for more information.
24 #[derive(Clone)]
25 pub 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 
new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> FormatWith<'a, I, F> where I: Iterator, F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result31 pub fn new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> FormatWith<'a, 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 
new_format_default<'a, I>(iter: I, separator: &'a str) -> Format<'a, I> where I: Iterator,41 pub fn new_format_default<'a, I>(iter: I, separator: &'a str) -> Format<'a, I>
42     where I: Iterator,
43 {
44     Format {
45         sep: separator,
46         inner: RefCell::new(Some(iter)),
47     }
48 }
49 
50 impl<'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 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result54     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             for elt in iter {
63                 if self.sep.len() > 0 {
64 
65                     f.write_str(self.sep)?;
66                 }
67                 format(elt, &mut |disp: &dyn fmt::Display| disp.fmt(f))?;
68             }
69         }
70         Ok(())
71     }
72 }
73 
74 impl<'a, I> Format<'a, I>
75     where I: Iterator,
76 {
format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result where F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,77     fn format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result
78         where F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,
79     {
80         let mut iter = match self.inner.borrow_mut().take() {
81             Some(t) => t,
82             None => panic!("Format: was already formatted once"),
83         };
84 
85         if let Some(fst) = iter.next() {
86             cb(&fst, f)?;
87             for elt in iter {
88                 if self.sep.len() > 0 {
89                     f.write_str(self.sep)?;
90                 }
91                 cb(&elt, f)?;
92             }
93         }
94         Ok(())
95     }
96 }
97 
98 macro_rules! impl_format {
99     ($($fmt_trait:ident)*) => {
100         $(
101             impl<'a, I> fmt::$fmt_trait for Format<'a, I>
102                 where I: Iterator,
103                       I::Item: fmt::$fmt_trait,
104             {
105                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106                     self.format(f, fmt::$fmt_trait::fmt)
107                 }
108             }
109         )*
110     }
111 }
112 
113 impl_format!{Display Debug
114              UpperExp LowerExp UpperHex LowerHex Octal Binary Pointer}
115