1 //! Formatting utils
2 
3 use std::cell::RefCell;
4 use std::fmt;
5 
6 /// Format the iterator like a map
7 pub struct DebugMap<F>(pub F);
8 
9 impl<'a, F, I, K, V> fmt::Debug for DebugMap<F>
10 where
11     F: Fn() -> I,
12     I: IntoIterator<Item = (K, V)>,
13     K: fmt::Debug,
14     V: fmt::Debug,
15 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result16     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17         f.debug_map().entries((self.0)()).finish()
18     }
19 }
20 
21 /// Avoid "pretty" debug
22 pub struct NoPretty<T>(pub T);
23 
24 impl<T> fmt::Debug for NoPretty<T>
25 where
26     T: fmt::Debug,
27 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result28     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29         write!(f, "{:?}", self.0)
30     }
31 }
32 
33 /// Format all iterator elements lazily, separated by `sep`.
34 ///
35 /// The format value can only be formatted once, after that the iterator is
36 /// exhausted.
37 ///
38 /// See [`.format()`](../trait.Itertools.html#method.format)
39 /// for more information.
40 #[derive(Clone)]
41 pub struct Format<'a, I> {
42     sep: &'a str,
43     /// Format uses interior mutability because Display::fmt takes &self.
44     inner: RefCell<Option<I>>,
45 }
46 
47 pub trait IterFormatExt: Iterator {
format(self, separator: &str) -> Format<Self> where Self: Sized,48     fn format(self, separator: &str) -> Format<Self>
49     where
50         Self: Sized,
51     {
52         Format {
53             sep: separator,
54             inner: RefCell::new(Some(self)),
55         }
56     }
57 }
58 
59 impl<I> IterFormatExt for I where I: Iterator {}
60 
61 impl<'a, I> Format<'a, I>
62 where
63     I: Iterator,
64 {
format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result where F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,65     fn format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result
66     where
67         F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,
68     {
69         let mut iter = match self.inner.borrow_mut().take() {
70             Some(t) => t,
71             None => panic!("Format: was already formatted once"),
72         };
73 
74         if let Some(fst) = iter.next() {
75             cb(&fst, f)?;
76             for elt in iter {
77                 if !self.sep.is_empty() {
78                     f.write_str(self.sep)?;
79                 }
80                 cb(&elt, f)?;
81             }
82         }
83         Ok(())
84     }
85 }
86 
87 macro_rules! impl_format {
88     ($($fmt_trait:ident)*) => {
89         $(
90             impl<'a, I> fmt::$fmt_trait for Format<'a, I>
91                 where I: Iterator,
92                       I::Item: fmt::$fmt_trait,
93             {
94                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95                     self.format(f, fmt::$fmt_trait::fmt)
96                 }
97             }
98         )*
99     }
100 }
101 
102 impl_format!(Debug);
103