/rust/registry/src/index.crates.io-1949cf8c6b5b557f/itertools-0.14.0/src/format.rs
Line | Count | Source |
1 | | use std::cell::Cell; |
2 | | use std::fmt; |
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()`](crate::Itertools::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: Cell<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()`](crate::Itertools::format) |
22 | | /// for more information. |
23 | | pub struct Format<'a, I> { |
24 | | sep: &'a str, |
25 | | /// `Format` uses interior mutability because `Display::fmt` takes `&self`. |
26 | | inner: Cell<Option<I>>, |
27 | | } |
28 | | |
29 | 0 | pub fn new_format<I, F>(iter: I, separator: &str, f: F) -> FormatWith<'_, I, F> |
30 | 0 | where |
31 | 0 | I: Iterator, |
32 | 0 | F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result, |
33 | | { |
34 | 0 | FormatWith { |
35 | 0 | sep: separator, |
36 | 0 | inner: Cell::new(Some((iter, f))), |
37 | 0 | } |
38 | 0 | } |
39 | | |
40 | 0 | pub fn new_format_default<I>(iter: I, separator: &str) -> Format<'_, I> |
41 | 0 | where |
42 | 0 | I: Iterator, |
43 | | { |
44 | 0 | Format { |
45 | 0 | sep: separator, |
46 | 0 | inner: Cell::new(Some(iter)), |
47 | 0 | } |
48 | 0 | } |
49 | | |
50 | | impl<I, F> fmt::Display for FormatWith<'_, I, F> |
51 | | where |
52 | | I: Iterator, |
53 | | F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result, |
54 | | { |
55 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
56 | 0 | let (mut iter, mut format) = match self.inner.take() { |
57 | 0 | Some(t) => t, |
58 | 0 | None => panic!("FormatWith: was already formatted once"), |
59 | | }; |
60 | | |
61 | 0 | if let Some(fst) = iter.next() { |
62 | 0 | format(fst, &mut |disp: &dyn fmt::Display| disp.fmt(f))?; |
63 | 0 | iter.try_for_each(|elt| { |
64 | 0 | if !self.sep.is_empty() { |
65 | 0 | f.write_str(self.sep)?; |
66 | 0 | } |
67 | 0 | format(elt, &mut |disp: &dyn fmt::Display| disp.fmt(f)) |
68 | 0 | })?; |
69 | 0 | } |
70 | 0 | Ok(()) |
71 | 0 | } |
72 | | } |
73 | | |
74 | | impl<I, F> fmt::Debug for FormatWith<'_, I, F> |
75 | | where |
76 | | I: Iterator, |
77 | | F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result, |
78 | | { |
79 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
80 | 0 | fmt::Display::fmt(self, f) |
81 | 0 | } |
82 | | } |
83 | | |
84 | | impl<I> Format<'_, I> |
85 | | where |
86 | | I: Iterator, |
87 | | { |
88 | 0 | fn format( |
89 | 0 | &self, |
90 | 0 | f: &mut fmt::Formatter, |
91 | 0 | cb: fn(&I::Item, &mut fmt::Formatter) -> fmt::Result, |
92 | 0 | ) -> fmt::Result { |
93 | 0 | let mut iter = match self.inner.take() { |
94 | 0 | Some(t) => t, |
95 | 0 | None => panic!("Format: was already formatted once"), |
96 | | }; |
97 | | |
98 | 0 | if let Some(fst) = iter.next() { |
99 | 0 | cb(&fst, f)?; |
100 | 0 | iter.try_for_each(|elt| { |
101 | 0 | if !self.sep.is_empty() { |
102 | 0 | f.write_str(self.sep)?; |
103 | 0 | } |
104 | 0 | cb(&elt, f) |
105 | 0 | })?; |
106 | 0 | } |
107 | 0 | Ok(()) |
108 | 0 | } |
109 | | } |
110 | | |
111 | | macro_rules! impl_format { |
112 | | ($($fmt_trait:ident)*) => { |
113 | | $( |
114 | | impl<'a, I> fmt::$fmt_trait for Format<'a, I> |
115 | | where I: Iterator, |
116 | | I::Item: fmt::$fmt_trait, |
117 | | { |
118 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
119 | 0 | self.format(f, fmt::$fmt_trait::fmt) |
120 | 0 | } Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Display>::fmt Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::UpperExp>::fmt Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::LowerExp>::fmt Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Pointer>::fmt |
121 | | } |
122 | | )* |
123 | | } |
124 | | } |
125 | | |
126 | | impl_format! {Display Debug UpperExp LowerExp UpperHex LowerHex Octal Binary Pointer} |
127 | | |
128 | | impl<I, F> Clone for FormatWith<'_, I, F> |
129 | | where |
130 | | (I, F): Clone, |
131 | | { |
132 | 0 | fn clone(&self) -> Self { |
133 | | struct PutBackOnDrop<'r, 'a, I, F> { |
134 | | into: &'r FormatWith<'a, I, F>, |
135 | | inner: Option<(I, F)>, |
136 | | } |
137 | | // This ensures we preserve the state of the original `FormatWith` if `Clone` panics |
138 | | impl<I, F> Drop for PutBackOnDrop<'_, '_, I, F> { |
139 | 0 | fn drop(&mut self) { |
140 | 0 | self.into.inner.set(self.inner.take()) |
141 | 0 | } |
142 | | } |
143 | 0 | let pbod = PutBackOnDrop { |
144 | 0 | inner: self.inner.take(), |
145 | 0 | into: self, |
146 | 0 | }; |
147 | 0 | Self { |
148 | 0 | inner: Cell::new(pbod.inner.clone()), |
149 | 0 | sep: self.sep, |
150 | 0 | } |
151 | 0 | } |
152 | | } |
153 | | |
154 | | impl<I> Clone for Format<'_, I> |
155 | | where |
156 | | I: Clone, |
157 | | { |
158 | 0 | fn clone(&self) -> Self { |
159 | | struct PutBackOnDrop<'r, 'a, I> { |
160 | | into: &'r Format<'a, I>, |
161 | | inner: Option<I>, |
162 | | } |
163 | | // This ensures we preserve the state of the original `FormatWith` if `Clone` panics |
164 | | impl<I> Drop for PutBackOnDrop<'_, '_, I> { |
165 | 0 | fn drop(&mut self) { |
166 | 0 | self.into.inner.set(self.inner.take()) |
167 | 0 | } |
168 | | } |
169 | 0 | let pbod = PutBackOnDrop { |
170 | 0 | inner: self.inner.take(), |
171 | 0 | into: self, |
172 | 0 | }; |
173 | 0 | Self { |
174 | 0 | inner: Cell::new(pbod.inner.clone()), |
175 | 0 | sep: self.sep, |
176 | 0 | } |
177 | 0 | } |
178 | | } |