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}