debug3/formatter.rs
1use crate::{
2 builders::{self, DebugList, DebugMap, DebugNamedList, DebugSet, DebugStruct, DebugTuple},
3 Formatter,
4};
5
6impl Formatter {
7 /// Creates a [`DebugStruct`] builder designed to assist with creation of
8 /// [`crate::Debug`] implementations for structs.
9 ///
10 /// # Examples
11 ///
12 /// ```rust
13 /// use debug3::{pprint, Debug, Formatter};
14 /// use std::net::Ipv4Addr;
15 ///
16 /// struct Foo {
17 /// bar: i32,
18 /// baz: String,
19 /// addr: Ipv4Addr,
20 /// }
21 ///
22 /// impl Debug for Foo {
23 /// fn fmt(&self, fmt: &mut Formatter) {
24 /// fmt.debug_struct("Foo")
25 /// .field("bar", &self.bar)
26 /// .field("baz", &self.baz)
27 /// .field("addr", &format_args!("{}", self.addr))
28 /// .finish()
29 /// }
30 /// }
31 ///
32 /// assert_eq!(
33 /// "\
34 /// Foo {
35 /// bar: 10,
36 /// baz: \"Hello World\",
37 /// addr: 127.0.0.1,
38 /// }",
39 /// pprint(Foo {
40 /// bar: 10,
41 /// baz: "Hello World".to_string(),
42 /// addr: Ipv4Addr::new(127, 0, 0, 1),
43 /// })
44 /// );
45 /// ```
46 pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b> {
47 builders::strukt::new(self, name)
48 }
49
50 /// Creates a `DebugTuple` builder designed to assist with creation of
51 /// `fmt::Debug` implementations for tuple structs.
52 ///
53 /// # Examples
54 ///
55 /// ```rust
56 /// use debug3::{pprint, Debug, Formatter};
57 /// use std::marker::PhantomData;
58 ///
59 /// struct Foo<T>(i32, String, PhantomData<T>);
60 ///
61 /// impl<T> Debug for Foo<T> {
62 /// fn fmt(&self, fmt: &mut Formatter) {
63 /// fmt.debug_tuple("Foo")
64 /// .field(&self.0)
65 /// .field(&self.1)
66 /// .field(&format_args!("_"))
67 /// .finish()
68 /// }
69 /// }
70 ///
71 /// assert_eq!(
72 /// "Foo(10, \"Hello\", _)",
73 /// pprint(Foo(10, "Hello".to_string(), PhantomData::<u8>))
74 /// );
75 /// ```
76 pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b> {
77 builders::tuple::new(self, name)
78 }
79
80 /// Creates a `DebugList` builder designed to assist with creation of
81 /// `fmt::Debug` implementations for list-like structures.
82 ///
83 /// # Examples
84 ///
85 /// ```rust
86 /// use debug3::{pprint, Debug, Formatter};
87 ///
88 /// struct Foo(Vec<i32>);
89 ///
90 /// impl Debug for Foo {
91 /// fn fmt(&self, fmt: &mut Formatter) {
92 /// fmt.debug_list().entries(self.0.iter()).finish()
93 /// }
94 /// }
95 ///
96 /// assert_eq!(pprint(Foo(vec![10, 11])), "[10, 11]");
97 /// ```
98 pub fn debug_list(&mut self) -> DebugList<'_> {
99 builders::list::new(self)
100 }
101
102 /// Creates a `DebugList` builder designed to assist with creation of
103 /// `fmt::Debug` implementations for list-like structures with names.
104 ///
105 /// # Examples
106 ///
107 /// ```rust
108 /// use debug3::{pprint, Debug, Formatter};
109 ///
110 /// struct Foo(Vec<i32>);
111 ///
112 /// impl Debug for Foo {
113 /// fn fmt(&self, fmt: &mut Formatter) {
114 /// fmt.debug_named_list("Foo").entries(self.0.iter()).finish()
115 /// }
116 /// }
117 ///
118 /// assert_eq!(pprint(Foo(vec![10, 11])), "Foo [10, 11]");
119 /// ```
120 pub fn debug_named_list(&mut self, name: &str) -> DebugNamedList<'_> {
121 builders::named_list::new(self, name)
122 }
123
124 /// Creates a `DebugSet` builder designed to assist with creation of
125 /// `fmt::Debug` implementations for set-like structures.
126 ///
127 /// # Examples
128 ///
129 /// ```rust
130 /// use debug3::{pprint, Debug, Formatter};
131 ///
132 /// struct Foo(Vec<i32>);
133 ///
134 /// impl Debug for Foo {
135 /// fn fmt(&self, fmt: &mut Formatter) {
136 /// fmt.debug_set().entries(self.0.iter()).finish()
137 /// }
138 /// }
139 ///
140 /// assert_eq!(pprint(Foo(vec![10, 11])), "{10, 11}");
141 /// ```
142 pub fn debug_set(&mut self) -> DebugSet<'_> {
143 builders::set::new(self)
144 }
145
146 /// Creates a `DebugMap` builder designed to assist with creation of
147 /// `fmt::Debug` implementations for map-like structures.
148 ///
149 /// # Examples
150 ///
151 /// ```rust
152 /// use debug3::{pprint, Debug, Formatter};
153 ///
154 /// struct Foo(Vec<(String, i32)>);
155 ///
156 /// impl Debug for Foo {
157 /// fn fmt(&self, fmt: &mut Formatter) {
158 /// fmt.debug_map()
159 /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
160 /// .finish()
161 /// }
162 /// }
163 ///
164 /// assert_eq!(
165 /// pprint(Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
166 /// r#"{"A": 10, "B": 11}"#
167 /// );
168 /// ```
169 pub fn debug_map(&mut self) -> DebugMap<'_> {
170 builders::map::new(self)
171 }
172
173 /// Escape hatch to allow direct writing of values throug their
174 /// [`std::fmt::Debug`] impl.
175 ///
176 /// Avoid this method whenever possible. It is likely to mess up your day.
177 /// Try to use the builder methods instead.
178 ///
179 /// ```rust
180 /// # use std::ops::Range;
181 /// # use debug3::{Debug, Formatter, pprint};
182 ///
183 /// struct Expr {
184 /// kind: ExprKind,
185 /// span: Range<usize>,
186 /// }
187 ///
188 /// #[derive(Debug)]
189 /// enum ExprKind {
190 /// BinOp {
191 /// lhs: Box<Expr>,
192 /// op: char,
193 /// rhs: Box<Expr>,
194 /// },
195 /// Int(i32),
196 /// }
197 ///
198 /// impl Debug for Expr {
199 /// fn fmt(&self, f: &mut Formatter) {
200 /// Debug::fmt(&self.kind, f);
201 /// f.write_display(" @ ");
202 /// f.write_debug(&self.span);
203 /// }
204 /// }
205 ///
206 /// // 1 + 3 + 4
207 /// let expr = Expr {
208 /// kind: ExprKind::BinOp {
209 /// lhs: Box::new(Expr {
210 /// kind: ExprKind::BinOp {
211 /// lhs: Box::new(Expr {
212 /// kind: ExprKind::Int(1),
213 /// span: 0..1,
214 /// }),
215 /// op: '+',
216 /// rhs: Box::new(Expr {
217 /// kind: ExprKind::Int(3),
218 /// span: 4..5,
219 /// }),
220 /// },
221 /// span: 0..5,
222 /// }),
223 /// op: '+',
224 /// rhs: Box::new(Expr {
225 /// kind: ExprKind::Int(4),
226 /// span: 8..9,
227 /// }),
228 /// },
229 /// span: 8..9,
230 /// };
231 ///
232 /// assert_eq!(
233 /// pprint(expr),
234 /// r"BinOp {
235 /// lhs: BinOp {
236 /// lhs: Int(1) @ 0..1,
237 /// op: '+',
238 /// rhs: Int(3) @ 4..5,
239 /// } @ 0..5,
240 /// op: '+',
241 /// rhs: Int(4) @ 8..9,
242 /// } @ 8..9"
243 /// );
244 /// ```
245 pub fn write_debug<T: std::fmt::Debug>(&mut self, val: T) {
246 let s = format!("{:?}", val);
247 self.word(s);
248 }
249
250 /// Escape hatch to allow direct writing of values throug their
251 /// [`std::fmt::Debug`] impl.
252 ///
253 /// Avoid this method whenever possible. It is likely to mess up your day.
254 /// Try to use the builder methods instead.
255 ///
256 /// See also [`Formatter::write_debug`]
257 pub fn write_display<T: std::fmt::Display>(&mut self, val: T) {
258 let s = format!("{}", val);
259 self.word(s);
260 }
261}