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