dbg_pls/
debug_set.rs

1use crate::{DebugPls, Formatter};
2
3/// A helper designed to assist with creation of
4/// [`DebugPls`] implementations for sets.
5///
6/// # Examples
7///
8/// ```rust
9/// use dbg_pls::{pretty, DebugPls, Formatter};
10/// use std::collections::BTreeSet;
11///
12/// struct Foo(BTreeSet<String>);
13///
14/// impl DebugPls for Foo {
15///     fn fmt(&self, f: Formatter) {
16///         f.debug_set().entries(&self.0).finish()
17///     }
18/// }
19/// let mut value = Foo(BTreeSet::from([
20///     "Hello".to_string(),
21///     "World".to_string(),
22/// ]));
23/// assert_eq!(
24///     format!("{}", pretty(&value)),
25/// "{
26///     \"Hello\";
27///     \"World\"
28/// }",
29/// );
30/// ```
31pub struct DebugSet<'a> {
32    formatter: Formatter<'a>,
33    set: syn::Block,
34}
35
36impl<'a> DebugSet<'a> {
37    pub(crate) fn new(formatter: Formatter<'a>) -> Self {
38        DebugSet {
39            formatter,
40            set: syn::Block {
41                brace_token: syn::token::Brace::default(),
42                stmts: vec![],
43            },
44        }
45    }
46
47    /// Adds the entry to the set output.
48    #[must_use]
49    pub fn entry(mut self, value: &dyn DebugPls) -> Self {
50        let expr = Formatter::process(value);
51        self.set
52            .stmts
53            .push(syn::Stmt::Expr(expr, Some(syn::token::Semi::default())));
54        self
55    }
56
57    /// Adds all the entries to the set output.
58    #[must_use]
59    pub fn entries<V, I>(self, entries: I) -> Self
60    where
61        V: DebugPls,
62        I: IntoIterator<Item = V>,
63    {
64        entries.into_iter().fold(self, |f, entry| f.entry(&entry))
65    }
66
67    /// Closes off the set.
68    pub fn finish(mut self) {
69        // remove the last semicolon
70        if let Some(syn::Stmt::Expr(entry, Some(_))) = self.set.stmts.pop() {
71            self.set.stmts.push(syn::Stmt::Expr(entry, None));
72        }
73
74        self.formatter.write_expr(syn::ExprBlock {
75            attrs: vec![],
76            label: None,
77            block: self.set,
78        });
79    }
80}