1use std::cell::RefCell;
4use std::fmt;
5
6pub 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
21pub 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#[derive(Clone)]
41pub struct Format<'a, I> {
42 sep: &'a str,
43 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);