petgraph/
iter_format.rs

1//! Formatting utils
2
3use std::cell::RefCell;
4use std::fmt;
5
6/// Format the iterator like a map
7pub struct DebugMap<F>(pub F);
8
9impl<'a, F, I, K, V> fmt::Debug for DebugMap<F>
10    where F: Fn() -> I,
11          I: IntoIterator<Item=(K, V)>,
12          K: fmt::Debug,
13          V: fmt::Debug,
14{
15    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
16        f.debug_map()
17         .entries((self.0)())
18         .finish()
19    }
20}
21
22/// Avoid "pretty" debug
23pub struct NoPretty<T>(pub T);
24
25impl<T> fmt::Debug for NoPretty<T>
26    where T: fmt::Debug,
27{
28    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)]
41pub 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
47pub trait IterFormatExt : Iterator {
48    fn format(self, separator: &str) -> Format<Self>
49        where Self: Sized
50    {
51        Format {
52            sep: separator,
53            inner: RefCell::new(Some(self)),
54        }
55    }
56}
57
58impl<I> IterFormatExt for I where I: Iterator { }
59
60
61impl<'a, I> Format<'a, I>
62    where I: Iterator,
63{
64    fn format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result
65        where F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,
66    {
67        let mut iter = match self.inner.borrow_mut().take() {
68            Some(t) => t,
69            None => panic!("Format: was already formatted once"),
70        };
71
72        if let Some(fst) = iter.next() {
73            try!(cb(&fst, f));
74            for elt in iter {
75                if !self.sep.is_empty() {
76                    try!(f.write_str(self.sep));
77                }
78                try!(cb(&elt, f));
79            }
80        }
81        Ok(())
82    }
83}
84
85macro_rules! impl_format {
86    ($($fmt_trait:ident)*) => {
87        $(
88            impl<'a, I> fmt::$fmt_trait for Format<'a, I>
89                where I: Iterator,
90                      I::Item: fmt::$fmt_trait,
91            {
92                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93                    self.format(f, fmt::$fmt_trait::fmt)
94                }
95            }
96        )*
97    }
98}
99
100impl_format!(Debug);