xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/itertools-0.11.0/src/format.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 
new_format<I, F>(iter: I, separator: &str, f: F) -> FormatWith<'_, I, F> where I: Iterator, F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,29 pub fn new_format<I, F>(iter: I, separator: &str, f: F) -> FormatWith<'_, I, F>
30 where
31     I: Iterator,
32     F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,
33 {
34     FormatWith {
35         sep: separator,
36         inner: Cell::new(Some((iter, f))),
37     }
38 }
39 
new_format_default<I>(iter: I, separator: &str) -> Format<'_, I> where I: Iterator,40 pub fn new_format_default<I>(iter: I, separator: &str) -> Format<'_, I>
41 where
42     I: Iterator,
43 {
44     Format {
45         sep: separator,
46         inner: Cell::new(Some(iter)),
47     }
48 }
49 
50 impl<'a, I, F> fmt::Display for FormatWith<'a, I, F>
51 where
52     I: Iterator,
53     F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,
54 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result55     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56         let (mut iter, mut format) = match self.inner.take() {
57             Some(t) => t,
58             None => panic!("FormatWith: was already formatted once"),
59         };
60 
61         if let Some(fst) = iter.next() {
62             format(fst, &mut |disp: &dyn fmt::Display| disp.fmt(f))?;
63             iter.try_for_each(|elt| {
64                 if !self.sep.is_empty() {
65                     f.write_str(self.sep)?;
66                 }
67                 format(elt, &mut |disp: &dyn fmt::Display| disp.fmt(f))
68             })?;
69         }
70         Ok(())
71     }
72 }
73 
74 impl<'a, I> Format<'a, I>
75 where
76     I: Iterator,
77 {
format( &self, f: &mut fmt::Formatter, cb: fn(&I::Item, &mut fmt::Formatter) -> fmt::Result, ) -> fmt::Result78     fn format(
79         &self,
80         f: &mut fmt::Formatter,
81         cb: fn(&I::Item, &mut fmt::Formatter) -> fmt::Result,
82     ) -> fmt::Result {
83         let mut iter = match self.inner.take() {
84             Some(t) => t,
85             None => panic!("Format: was already formatted once"),
86         };
87 
88         if let Some(fst) = iter.next() {
89             cb(&fst, f)?;
90             iter.try_for_each(|elt| {
91                 if !self.sep.is_empty() {
92                     f.write_str(self.sep)?;
93                 }
94                 cb(&elt, f)
95             })?;
96         }
97         Ok(())
98     }
99 }
100 
101 macro_rules! impl_format {
102     ($($fmt_trait:ident)*) => {
103         $(
104             impl<'a, I> fmt::$fmt_trait for Format<'a, I>
105                 where I: Iterator,
106                       I::Item: fmt::$fmt_trait,
107             {
108                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109                     self.format(f, fmt::$fmt_trait::fmt)
110                 }
111             }
112         )*
113     }
114 }
115 
116 impl_format! {Display Debug UpperExp LowerExp UpperHex LowerHex Octal Binary Pointer}
117 
118 impl<'a, I, F> Clone for FormatWith<'a, I, F>
119 where
120     (I, F): Clone,
121 {
clone(&self) -> Self122     fn clone(&self) -> Self {
123         struct PutBackOnDrop<'r, 'a, I, F> {
124             into: &'r FormatWith<'a, I, F>,
125             inner: Option<(I, F)>,
126         }
127         // This ensures we preserve the state of the original `FormatWith` if `Clone` panics
128         impl<'r, 'a, I, F> Drop for PutBackOnDrop<'r, 'a, I, F> {
129             fn drop(&mut self) {
130                 self.into.inner.set(self.inner.take())
131             }
132         }
133         let pbod = PutBackOnDrop {
134             inner: self.inner.take(),
135             into: self,
136         };
137         Self {
138             inner: Cell::new(pbod.inner.clone()),
139             sep: self.sep,
140         }
141     }
142 }
143 
144 impl<'a, I> Clone for Format<'a, I>
145 where
146     I: Clone,
147 {
clone(&self) -> Self148     fn clone(&self) -> Self {
149         struct PutBackOnDrop<'r, 'a, I> {
150             into: &'r Format<'a, I>,
151             inner: Option<I>,
152         }
153         // This ensures we preserve the state of the original `FormatWith` if `Clone` panics
154         impl<'r, 'a, I> Drop for PutBackOnDrop<'r, 'a, I> {
155             fn drop(&mut self) {
156                 self.into.inner.set(self.inner.take())
157             }
158         }
159         let pbod = PutBackOnDrop {
160             inner: self.inner.take(),
161             into: self,
162         };
163         Self {
164             inner: Cell::new(pbod.inner.clone()),
165             sep: self.sep,
166         }
167     }
168 }
169