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<F, I, K, V> fmt::Debug for DebugMap<F>
10where
11    F: Fn() -> I,
12    I: IntoIterator<Item = (K, V)>,
13    K: fmt::Debug,
14    V: fmt::Debug,
15{
16    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17        f.debug_map().entries((self.0)()).finish()
18    }
19}
20
21/// Avoid "pretty" debug
22pub struct NoPretty<T>(pub T);
23
24impl<T> fmt::Debug for NoPretty<T>
25where
26    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
50        Self: Sized,
51    {
52        Format {
53            sep: separator,
54            inner: RefCell::new(Some(self)),
55        }
56    }
57}
58
59impl<I> IterFormatExt for I where I: Iterator {}
60
61impl<I> Format<'_, I>
62where
63    I: Iterator,
64{
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
87macro_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
102impl_format!(Debug);