Coverage Report

Created: 2025-12-14 07:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}