Coverage Report

Created: 2024-05-20 06:38

/rust/registry/src/index.crates.io-6f17d22bba15001f/itertools-0.11.0/src/format.rs
Line
Count
Source (jump to first uncovered line)
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
0
{
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
0
{
44
0
    Format {
45
0
        sep: separator,
46
0
        inner: Cell::new(Some(iter)),
47
0
    }
48
0
}
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
{
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<'a, I> Format<'a, I>
75
where
76
    I: Iterator,
77
{
78
0
    fn format(
79
0
        &self,
80
0
        f: &mut fmt::Formatter,
81
0
        cb: fn(&I::Item, &mut fmt::Formatter) -> fmt::Result,
82
0
    ) -> fmt::Result {
83
0
        let mut iter = match self.inner.take() {
84
0
            Some(t) => t,
85
0
            None => panic!("Format: was already formatted once"),
86
        };
87
88
0
        if let Some(fst) = iter.next() {
89
0
            cb(&fst, f)?;
90
0
            iter.try_for_each(|elt| {
91
0
                if !self.sep.is_empty() {
92
0
                    f.write_str(self.sep)?;
93
0
                }
94
0
                cb(&elt, f)
95
0
            })?;
96
0
        }
97
0
        Ok(())
98
0
    }
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
0
                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109
0
                    self.format(f, fmt::$fmt_trait::fmt)
110
0
                }
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Octal>::fmt
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Binary>::fmt
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::LowerExp>::fmt
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Pointer>::fmt
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Debug>::fmt
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::UpperExp>::fmt
Unexecuted instantiation: <itertools::format::Format<_> as core::fmt::Display>::fmt
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
{
122
0
    fn clone(&self) -> Self {
123
0
        struct PutBackOnDrop<'r, 'a, I, F> {
124
0
            into: &'r FormatWith<'a, I, F>,
125
0
            inner: Option<(I, F)>,
126
0
        }
127
0
        // This ensures we preserve the state of the original `FormatWith` if `Clone` panics
128
0
        impl<'r, 'a, I, F> Drop for PutBackOnDrop<'r, 'a, I, F> {
129
0
            fn drop(&mut self) {
130
0
                self.into.inner.set(self.inner.take())
131
0
            }
132
0
        }
133
0
        let pbod = PutBackOnDrop {
134
0
            inner: self.inner.take(),
135
0
            into: self,
136
0
        };
137
0
        Self {
138
0
            inner: Cell::new(pbod.inner.clone()),
139
0
            sep: self.sep,
140
0
        }
141
0
    }
142
}
143
144
impl<'a, I> Clone for Format<'a, I>
145
where
146
    I: Clone,
147
{
148
0
    fn clone(&self) -> Self {
149
0
        struct PutBackOnDrop<'r, 'a, I> {
150
0
            into: &'r Format<'a, I>,
151
0
            inner: Option<I>,
152
0
        }
153
0
        // This ensures we preserve the state of the original `FormatWith` if `Clone` panics
154
0
        impl<'r, 'a, I> Drop for PutBackOnDrop<'r, 'a, I> {
155
0
            fn drop(&mut self) {
156
0
                self.into.inner.set(self.inner.take())
157
0
            }
158
0
        }
159
0
        let pbod = PutBackOnDrop {
160
0
            inner: self.inner.take(),
161
0
            into: self,
162
0
        };
163
0
        Self {
164
0
            inner: Cell::new(pbod.inner.clone()),
165
0
            sep: self.sep,
166
0
        }
167
0
    }
168
}