petgraph/
iter_format.rs

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