]> git.proxmox.com Git - rustc.git/blob - vendor/itertools-0.7.8/src/format.rs
New upstream version 1.34.2+dfsg1
[rustc.git] / vendor / itertools-0.7.8 / src / format.rs
1 use std::fmt;
2 use std::cell::RefCell;
3
4 /// Format all iterator elements lazily, separated by `sep`.
5 ///
6 /// The format value can only be formatted once, after that the iterator is
7 /// exhausted.
8 ///
9 /// See [`.format_with()`](../trait.Itertools.html#method.format_with) for more information.
10 pub struct FormatWith<'a, I, F> {
11 sep: &'a str,
12 /// FormatWith uses interior mutability because Display::fmt takes &self.
13 inner: RefCell<Option<(I, F)>>,
14 }
15
16 /// Format all iterator elements lazily, separated by `sep`.
17 ///
18 /// The format value can only be formatted once, after that the iterator is
19 /// exhausted.
20 ///
21 /// See [`.format()`](../trait.Itertools.html#method.format)
22 /// for more information.
23 #[derive(Clone)]
24 pub struct Format<'a, I> {
25 sep: &'a str,
26 /// Format uses interior mutability because Display::fmt takes &self.
27 inner: RefCell<Option<I>>,
28 }
29
30 pub fn new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> FormatWith<'a, I, F>
31 where I: Iterator,
32 F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result
33 {
34 FormatWith {
35 sep: separator,
36 inner: RefCell::new(Some((iter, f))),
37 }
38 }
39
40 pub fn new_format_default<'a, I>(iter: I, separator: &'a str) -> Format<'a, I>
41 where I: Iterator,
42 {
43 Format {
44 sep: separator,
45 inner: RefCell::new(Some(iter)),
46 }
47 }
48
49 impl<'a, I, F> fmt::Display for FormatWith<'a, I, F>
50 where I: Iterator,
51 F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result
52 {
53 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54 let (mut iter, mut format) = match self.inner.borrow_mut().take() {
55 Some(t) => t,
56 None => panic!("FormatWith: was already formatted once"),
57 };
58
59 if let Some(fst) = iter.next() {
60 try!(format(fst, &mut |disp: &fmt::Display| disp.fmt(f)));
61 for elt in iter {
62 if self.sep.len() > 0 {
63
64 try!(f.write_str(self.sep));
65 }
66 try!(format(elt, &mut |disp: &fmt::Display| disp.fmt(f)));
67 }
68 }
69 Ok(())
70 }
71 }
72
73 impl<'a, I> Format<'a, I>
74 where I: Iterator,
75 {
76 fn format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result
77 where F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,
78 {
79 let mut iter = match self.inner.borrow_mut().take() {
80 Some(t) => t,
81 None => panic!("Format: was already formatted once"),
82 };
83
84 if let Some(fst) = iter.next() {
85 try!(cb(&fst, f));
86 for elt in iter {
87 if self.sep.len() > 0 {
88 try!(f.write_str(self.sep));
89 }
90 try!(cb(&elt, f));
91 }
92 }
93 Ok(())
94 }
95 }
96
97 macro_rules! impl_format {
98 ($($fmt_trait:ident)*) => {
99 $(
100 impl<'a, I> fmt::$fmt_trait for Format<'a, I>
101 where I: Iterator,
102 I::Item: fmt::$fmt_trait,
103 {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 self.format(f, fmt::$fmt_trait::fmt)
106 }
107 }
108 )*
109 }
110 }
111
112 impl_format!{Display Debug
113 UpperExp LowerExp UpperHex LowerHex Octal Binary Pointer}