ufmt/
helpers.rs

1use crate::{uDebug, uWrite, Formatter};
2
3impl<'w, W> Formatter<'w, W>
4where
5    W: uWrite + ?Sized,
6{
7    /// Creates a `DebugList` builder designed to assist with creation of `uDebug` implementations
8    /// for list-like structures.
9    pub fn debug_list(&mut self) -> Result<DebugList<'_, 'w, W>, W::Error> {
10        self.write_str("[")?;
11
12        if self.pretty {
13            self.indentation += 1;
14        }
15
16        Ok(DebugList {
17            first: true,
18            formatter: self,
19        })
20    }
21
22    /// Creates a `DebugMap` builder designed to assist with creation of `uDebug` implementations
23    /// for map-like structures.
24    pub fn debug_map(&mut self) -> Result<DebugMap<'_, 'w, W>, W::Error> {
25        self.write_str("{")?;
26
27        if self.pretty {
28            self.indentation += 1;
29        }
30
31        Ok(DebugMap {
32            first: true,
33            formatter: self,
34        })
35    }
36
37    /// Creates a `DebugSet` builder designed to assist with creation of `uDebug` implementations
38    /// for set-like structures.
39    pub fn debug_set(&mut self) -> Result<DebugSet<'_, 'w, W>, W::Error> {
40        self.write_str("{")?;
41
42        if self.pretty {
43            self.indentation += 1;
44        }
45
46        Ok(DebugSet {
47            first: true,
48            formatter: self,
49        })
50    }
51
52    /// Creates a `DebugStruct` builder designed to assist with creation of `uDebug` implementations
53    /// for structs.
54    pub fn debug_struct(&mut self, name: &str) -> Result<DebugStruct<'_, 'w, W>, W::Error> {
55        self.write_str(name)?;
56
57        if self.pretty {
58            self.indentation += 1;
59        }
60
61        Ok(DebugStruct {
62            first: true,
63            formatter: self,
64        })
65    }
66
67    /// Creates a `DebugTuple` builder designed to assist with creation of `uDebug` implementations
68    /// for tuple structs.
69    pub fn debug_tuple(&mut self, name: &str) -> Result<DebugTuple<'_, 'w, W>, W::Error> {
70        self.write_str(name)?;
71
72        if self.pretty {
73            self.indentation += 1;
74        }
75
76        Ok(DebugTuple {
77            fields: 0,
78            first: true,
79            formatter: self,
80            unnamed: name.is_empty(),
81        })
82    }
83}
84
85/// A struct to help with [`uDebug`] implementations.
86///
87/// This is useful when you wish to output a formatted list of items as a part of your
88/// [`uDebug::fmt`] implementation.
89///
90/// This can be constructed by the [`Formatter::debug_list`] method.
91pub struct DebugList<'f, 'w, W>
92where
93    W: uWrite + ?Sized,
94{
95    first: bool,
96    formatter: &'f mut Formatter<'w, W>,
97}
98
99impl<W> DebugList<'_, '_, W>
100where
101    W: uWrite + ?Sized,
102{
103    /// Adds a new entry to the list output.
104    pub fn entry(&mut self, entry: &impl uDebug) -> Result<&mut Self, W::Error> {
105        if self.first {
106            self.first = false;
107
108            if self.formatter.pretty {
109                self.formatter.write_str("\n")?;
110            }
111        } else if !self.formatter.pretty {
112            self.formatter.write_str(", ")?;
113        }
114
115        if self.formatter.pretty {
116            self.formatter.indent()?;
117        }
118
119        entry.fmt(self.formatter)?;
120
121        if self.formatter.pretty {
122            self.formatter.write_str(",\n")?;
123        }
124
125        Ok(self)
126    }
127
128    /// Adds the contents of an iterator of entries to the list output.
129    pub fn entries(
130        &mut self,
131        entries: impl IntoIterator<Item = impl uDebug>,
132    ) -> Result<&mut Self, W::Error> {
133        for entry in entries {
134            self.entry(&entry)?;
135        }
136
137        Ok(self)
138    }
139
140    /// Finishes output
141    pub fn finish(&mut self) -> Result<(), W::Error> {
142        if self.formatter.pretty {
143            self.formatter.indentation -= 1;
144            self.formatter.indent()?;
145        }
146
147        self.formatter.write_str("]")
148    }
149}
150
151/// A struct to help with [`uDebug`] implementations.
152///
153/// This is useful when you wish to output a formatted map as a part of your [`uDebug::fmt`]
154/// implementation.
155///
156/// This can be constructed by the [`Formatter::debug_map`] method.
157pub struct DebugMap<'f, 'w, W>
158where
159    W: uWrite + ?Sized,
160{
161    first: bool,
162    formatter: &'f mut Formatter<'w, W>,
163}
164
165impl<W> DebugMap<'_, '_, W>
166where
167    W: uWrite + ?Sized,
168{
169    /// Adds a new entry to the map output.
170    pub fn entry(&mut self, key: &impl uDebug, value: &impl uDebug) -> Result<&mut Self, W::Error> {
171        if self.first {
172            self.first = false;
173
174            if self.formatter.pretty {
175                self.formatter.write_str("\n")?;
176            }
177        } else if !self.formatter.pretty {
178            self.formatter.write_str(", ")?;
179        }
180
181        if self.formatter.pretty {
182            self.formatter.indent()?;
183        }
184
185        key.fmt(self.formatter)?;
186        self.formatter.write_str(": ")?;
187        value.fmt(self.formatter)?;
188
189        if self.formatter.pretty {
190            self.formatter.write_str(",\n")?;
191        }
192
193        Ok(self)
194    }
195
196    /// Adds the contents of an iterator of entries to the map output.
197    pub fn entries(
198        &mut self,
199        entries: impl IntoIterator<Item = (impl uDebug, impl uDebug)>,
200    ) -> Result<&mut Self, W::Error> {
201        for (k, v) in entries.into_iter() {
202            self.entry(&k, &v)?;
203        }
204
205        Ok(self)
206    }
207
208    /// Finishes output
209    pub fn finish(&mut self) -> Result<(), W::Error> {
210        self.formatter.write_str("}")
211    }
212}
213
214/// A struct to help with [`uDebug`] implementations.
215///
216/// This is useful when you wish to output a formatted set of items as a part of your
217/// [`uDebug::fmt`] implementation.
218///
219/// This can be constructed by the [`Formatter::debug_set`] method.
220pub struct DebugSet<'f, 'w, W>
221where
222    W: uWrite + ?Sized,
223{
224    first: bool,
225    formatter: &'f mut Formatter<'w, W>,
226}
227
228impl<W> DebugSet<'_, '_, W>
229where
230    W: uWrite + ?Sized,
231{
232    /// Adds a new entry to the set output.
233    pub fn entry(&mut self, entry: &impl uDebug) -> Result<&mut Self, W::Error> {
234        if self.first {
235            self.first = false;
236
237            if self.formatter.pretty {
238                self.formatter.write_str("\n")?;
239            }
240        } else if !self.formatter.pretty {
241            self.formatter.write_str(", ")?;
242        }
243
244        if self.formatter.pretty {
245            self.formatter.indent()?;
246        }
247
248        entry.fmt(self.formatter)?;
249
250        if self.formatter.pretty {
251            self.formatter.write_str(",\n")?;
252        }
253
254        Ok(self)
255    }
256
257    /// Adds the contents of an iterator of entries to the set output.
258    pub fn entries(
259        &mut self,
260        entries: impl IntoIterator<Item = impl uDebug>,
261    ) -> Result<&mut Self, W::Error> {
262        for entry in entries {
263            self.entry(&entry)?;
264        }
265
266        Ok(self)
267    }
268
269    /// Finishes output
270    pub fn finish(&mut self) -> Result<(), W::Error> {
271        self.formatter.write_str("}")
272    }
273}
274
275/// A struct to help with [`uDebug`] implementations.
276///
277/// This is useful when you wish to output a formatted struct as a part of your [`uDebug::fmt`]
278/// implementation.
279///
280/// This can be constructed by the [`Formatter::debug_struct`] method.
281pub struct DebugStruct<'f, 'w, W>
282where
283    W: uWrite + ?Sized,
284{
285    first: bool,
286    formatter: &'f mut Formatter<'w, W>,
287}
288
289impl<W> DebugStruct<'_, '_, W>
290where
291    W: uWrite + ?Sized,
292{
293    /// Adds a new field to the generated struct output.
294    pub fn field(&mut self, name: &str, value: &impl uDebug) -> Result<&mut Self, W::Error> {
295        if self.first {
296            self.first = false;
297
298            self.formatter.write_str(" {")?;
299
300            if self.formatter.pretty {
301                self.formatter.write_str("\n")?;
302            } else {
303                self.formatter.write_str(" ")?;
304            }
305        } else if !self.formatter.pretty {
306            self.formatter.write_str(", ")?;
307        }
308
309        if self.formatter.pretty {
310            self.formatter.indent()?;
311        }
312
313        self.formatter.write_str(name)?;
314        self.formatter.write_str(": ")?;
315        value.fmt(self.formatter)?;
316
317        if self.formatter.pretty {
318            self.formatter.write_str(",\n")?;
319        }
320
321        Ok(self)
322    }
323
324    /// Finishes output
325    pub fn finish(&mut self) -> Result<(), W::Error> {
326        if self.formatter.pretty {
327            self.formatter.indentation -= 1;
328        }
329
330        if !self.first {
331            if self.formatter.pretty {
332                self.formatter.indent()?;
333            } else {
334                self.formatter.write_str(" ")?;
335            }
336
337            self.formatter.write_str("}")?;
338        }
339
340        Ok(())
341    }
342}
343
344/// A struct to help with [`uDebug`] implementations.
345///
346/// This is useful when you wish to output a formatted tuple as a part of your [`uDebug::fmt`]
347/// implementation.
348///
349/// This can be constructed by the [`Formatter::debug_tuple`] method.
350pub struct DebugTuple<'f, 'w, W>
351where
352    W: uWrite + ?Sized,
353{
354    fields: u8,
355    first: bool,
356    formatter: &'f mut Formatter<'w, W>,
357    unnamed: bool,
358}
359
360impl<W> DebugTuple<'_, '_, W>
361where
362    W: uWrite + ?Sized,
363{
364    /// Adds a new field to the generated tuple struct output.
365    pub fn field(&mut self, value: &impl uDebug) -> Result<&mut Self, W::Error> {
366        self.fields += 1;
367
368        if self.first {
369            self.first = false;
370
371            self.formatter.write_str("(")?;
372
373            if self.formatter.pretty {
374                self.formatter.write_str("\n")?;
375            }
376        } else if !self.formatter.pretty {
377            self.formatter.write_str(", ")?;
378        }
379
380        if self.formatter.pretty {
381            self.formatter.indent()?;
382        }
383
384        value.fmt(self.formatter)?;
385
386        if self.formatter.pretty {
387            self.formatter.write_str(",\n")?;
388        }
389
390        Ok(self)
391    }
392
393    /// Finishes output
394    pub fn finish(&mut self) -> Result<(), W::Error> {
395        if self.formatter.pretty {
396            self.formatter.indentation -= 1;
397        }
398
399        if !self.first {
400            if self.formatter.pretty {
401                self.formatter.indent()?;
402            } else if self.unnamed && self.fields == 1 {
403                // this is a one-element tuple so we need a trailing comma
404                self.formatter.write_str(",")?;
405            }
406
407            self.formatter.write_str(")")?;
408        }
409
410        Ok(())
411    }
412}