1 | #![allow (unused_imports)] |
2 | |
3 | use crate::fmt::{self, Debug, Formatter}; |
4 | |
5 | struct PadAdapter<'buf, 'state> { |
6 | buf: &'buf mut (dyn fmt::Write + 'buf), |
7 | state: &'state mut PadAdapterState, |
8 | } |
9 | |
10 | struct PadAdapterState { |
11 | on_newline: bool, |
12 | } |
13 | |
14 | impl Default for PadAdapterState { |
15 | fn default() -> Self { |
16 | PadAdapterState { on_newline: true } |
17 | } |
18 | } |
19 | |
20 | impl<'buf, 'state> PadAdapter<'buf, 'state> { |
21 | fn wrap<'slot, 'fmt: 'buf + 'slot>( |
22 | fmt: &'fmt mut fmt::Formatter<'_>, |
23 | slot: &'slot mut Option<Self>, |
24 | state: &'state mut PadAdapterState, |
25 | ) -> fmt::Formatter<'slot> { |
26 | fmt.wrap_buf(wrap:move |buf: &mut dyn Write| slot.insert(PadAdapter { buf, state })) |
27 | } |
28 | } |
29 | |
30 | impl fmt::Write for PadAdapter<'_, '_> { |
31 | fn write_str(&mut self, s: &str) -> fmt::Result { |
32 | for s: &str in s.split_inclusive(' \n' ) { |
33 | if self.state.on_newline { |
34 | self.buf.write_str(" " )?; |
35 | } |
36 | |
37 | self.state.on_newline = s.ends_with(' \n' ); |
38 | self.buf.write_str(s)?; |
39 | } |
40 | |
41 | Ok(()) |
42 | } |
43 | |
44 | fn write_char(&mut self, c: char) -> fmt::Result { |
45 | if self.state.on_newline { |
46 | self.buf.write_str(" " )?; |
47 | } |
48 | self.state.on_newline = c == ' \n' ; |
49 | self.buf.write_char(c) |
50 | } |
51 | } |
52 | |
53 | /// A struct to help with [`fmt::Debug`](Debug) implementations. |
54 | /// |
55 | /// This is useful when you wish to output a formatted struct as a part of your |
56 | /// [`Debug::fmt`] implementation. |
57 | /// |
58 | /// This can be constructed by the [`Formatter::debug_struct`] method. |
59 | /// |
60 | /// # Examples |
61 | /// |
62 | /// ``` |
63 | /// use std::fmt; |
64 | /// |
65 | /// struct Foo { |
66 | /// bar: i32, |
67 | /// baz: String, |
68 | /// } |
69 | /// |
70 | /// impl fmt::Debug for Foo { |
71 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
72 | /// fmt.debug_struct("Foo" ) |
73 | /// .field("bar" , &self.bar) |
74 | /// .field("baz" , &self.baz) |
75 | /// .finish() |
76 | /// } |
77 | /// } |
78 | /// |
79 | /// assert_eq!( |
80 | /// format!("{:?}" , Foo { bar: 10, baz: "Hello World" .to_string() }), |
81 | /// r#"Foo { bar: 10, baz: "Hello World" }"# , |
82 | /// ); |
83 | /// ``` |
84 | #[must_use = "must eventually call `finish()` on Debug builders" ] |
85 | #[allow (missing_debug_implementations)] |
86 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
87 | #[rustc_diagnostic_item = "DebugStruct" ] |
88 | pub struct DebugStruct<'a, 'b: 'a> { |
89 | fmt: &'a mut fmt::Formatter<'b>, |
90 | result: fmt::Result, |
91 | has_fields: bool, |
92 | } |
93 | |
94 | pub(super) fn debug_struct_new<'a, 'b>( |
95 | fmt: &'a mut fmt::Formatter<'b>, |
96 | name: &str, |
97 | ) -> DebugStruct<'a, 'b> { |
98 | let result: Result<(), Error> = fmt.write_str(data:name); |
99 | DebugStruct { fmt, result, has_fields: false } |
100 | } |
101 | |
102 | impl<'a, 'b: 'a> DebugStruct<'a, 'b> { |
103 | /// Adds a new field to the generated struct output. |
104 | /// |
105 | /// # Examples |
106 | /// |
107 | /// ``` |
108 | /// use std::fmt; |
109 | /// |
110 | /// struct Bar { |
111 | /// bar: i32, |
112 | /// another: String, |
113 | /// } |
114 | /// |
115 | /// impl fmt::Debug for Bar { |
116 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
117 | /// fmt.debug_struct("Bar" ) |
118 | /// .field("bar" , &self.bar) // We add `bar` field. |
119 | /// .field("another" , &self.another) // We add `another` field. |
120 | /// // We even add a field which doesn't exist (because why not?). |
121 | /// .field("nonexistent_field" , &1) |
122 | /// .finish() // We're good to go! |
123 | /// } |
124 | /// } |
125 | /// |
126 | /// assert_eq!( |
127 | /// format!("{:?}" , Bar { bar: 10, another: "Hello World" .to_string() }), |
128 | /// r#"Bar { bar: 10, another: "Hello World", nonexistent_field: 1 }"# , |
129 | /// ); |
130 | /// ``` |
131 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
132 | pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut Self { |
133 | self.field_with(name, |f| value.fmt(f)) |
134 | } |
135 | |
136 | /// Adds a new field to the generated struct output. |
137 | /// |
138 | /// This method is equivalent to [`DebugStruct::field`], but formats the |
139 | /// value using a provided closure rather than by calling [`Debug::fmt`]. |
140 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
141 | pub fn field_with<F>(&mut self, name: &str, value_fmt: F) -> &mut Self |
142 | where |
143 | F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, |
144 | { |
145 | self.result = self.result.and_then(|_| { |
146 | if self.is_pretty() { |
147 | if !self.has_fields { |
148 | self.fmt.write_str(" { \n" )?; |
149 | } |
150 | let mut slot = None; |
151 | let mut state = Default::default(); |
152 | let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state); |
153 | writer.write_str(name)?; |
154 | writer.write_str(": " )?; |
155 | value_fmt(&mut writer)?; |
156 | writer.write_str(", \n" ) |
157 | } else { |
158 | let prefix = if self.has_fields { ", " } else { " { " }; |
159 | self.fmt.write_str(prefix)?; |
160 | self.fmt.write_str(name)?; |
161 | self.fmt.write_str(": " )?; |
162 | value_fmt(self.fmt) |
163 | } |
164 | }); |
165 | |
166 | self.has_fields = true; |
167 | self |
168 | } |
169 | |
170 | /// Marks the struct as non-exhaustive, indicating to the reader that there are some other |
171 | /// fields that are not shown in the debug representation. |
172 | /// |
173 | /// # Examples |
174 | /// |
175 | /// ``` |
176 | /// use std::fmt; |
177 | /// |
178 | /// struct Bar { |
179 | /// bar: i32, |
180 | /// hidden: f32, |
181 | /// } |
182 | /// |
183 | /// impl fmt::Debug for Bar { |
184 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
185 | /// fmt.debug_struct("Bar" ) |
186 | /// .field("bar" , &self.bar) |
187 | /// .finish_non_exhaustive() // Show that some other field(s) exist. |
188 | /// } |
189 | /// } |
190 | /// |
191 | /// assert_eq!( |
192 | /// format!("{:?}" , Bar { bar: 10, hidden: 1.0 }), |
193 | /// "Bar { bar: 10, .. }" , |
194 | /// ); |
195 | /// ``` |
196 | #[stable (feature = "debug_non_exhaustive" , since = "1.53.0" )] |
197 | pub fn finish_non_exhaustive(&mut self) -> fmt::Result { |
198 | self.result = self.result.and_then(|_| { |
199 | if self.has_fields { |
200 | if self.is_pretty() { |
201 | let mut slot = None; |
202 | let mut state = Default::default(); |
203 | let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state); |
204 | writer.write_str(".. \n" )?; |
205 | self.fmt.write_str("}" ) |
206 | } else { |
207 | self.fmt.write_str(", .. }" ) |
208 | } |
209 | } else { |
210 | self.fmt.write_str(" { .. }" ) |
211 | } |
212 | }); |
213 | self.result |
214 | } |
215 | |
216 | /// Finishes output and returns any error encountered. |
217 | /// |
218 | /// # Examples |
219 | /// |
220 | /// ``` |
221 | /// use std::fmt; |
222 | /// |
223 | /// struct Bar { |
224 | /// bar: i32, |
225 | /// baz: String, |
226 | /// } |
227 | /// |
228 | /// impl fmt::Debug for Bar { |
229 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
230 | /// fmt.debug_struct("Bar" ) |
231 | /// .field("bar" , &self.bar) |
232 | /// .field("baz" , &self.baz) |
233 | /// .finish() // You need to call it to "finish" the |
234 | /// // struct formatting. |
235 | /// } |
236 | /// } |
237 | /// |
238 | /// assert_eq!( |
239 | /// format!("{:?}" , Bar { bar: 10, baz: "Hello World" .to_string() }), |
240 | /// r#"Bar { bar: 10, baz: "Hello World" }"# , |
241 | /// ); |
242 | /// ``` |
243 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
244 | pub fn finish(&mut self) -> fmt::Result { |
245 | if self.has_fields { |
246 | self.result = self.result.and_then(|_| { |
247 | if self.is_pretty() { self.fmt.write_str("}" ) } else { self.fmt.write_str(" }" ) } |
248 | }); |
249 | } |
250 | self.result |
251 | } |
252 | |
253 | fn is_pretty(&self) -> bool { |
254 | self.fmt.alternate() |
255 | } |
256 | } |
257 | |
258 | /// A struct to help with [`fmt::Debug`](Debug) implementations. |
259 | /// |
260 | /// This is useful when you wish to output a formatted tuple as a part of your |
261 | /// [`Debug::fmt`] implementation. |
262 | /// |
263 | /// This can be constructed by the [`Formatter::debug_tuple`] method. |
264 | /// |
265 | /// # Examples |
266 | /// |
267 | /// ``` |
268 | /// use std::fmt; |
269 | /// |
270 | /// struct Foo(i32, String); |
271 | /// |
272 | /// impl fmt::Debug for Foo { |
273 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
274 | /// fmt.debug_tuple("Foo" ) |
275 | /// .field(&self.0) |
276 | /// .field(&self.1) |
277 | /// .finish() |
278 | /// } |
279 | /// } |
280 | /// |
281 | /// assert_eq!( |
282 | /// format!("{:?}" , Foo(10, "Hello World" .to_string())), |
283 | /// r#"Foo(10, "Hello World")"# , |
284 | /// ); |
285 | /// ``` |
286 | #[must_use = "must eventually call `finish()` on Debug builders" ] |
287 | #[allow (missing_debug_implementations)] |
288 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
289 | pub struct DebugTuple<'a, 'b: 'a> { |
290 | fmt: &'a mut fmt::Formatter<'b>, |
291 | result: fmt::Result, |
292 | fields: usize, |
293 | empty_name: bool, |
294 | } |
295 | |
296 | pub(super) fn debug_tuple_new<'a, 'b>( |
297 | fmt: &'a mut fmt::Formatter<'b>, |
298 | name: &str, |
299 | ) -> DebugTuple<'a, 'b> { |
300 | let result: Result<(), Error> = fmt.write_str(data:name); |
301 | DebugTuple { fmt, result, fields: 0, empty_name: name.is_empty() } |
302 | } |
303 | |
304 | impl<'a, 'b: 'a> DebugTuple<'a, 'b> { |
305 | /// Adds a new field to the generated tuple struct output. |
306 | /// |
307 | /// # Examples |
308 | /// |
309 | /// ``` |
310 | /// use std::fmt; |
311 | /// |
312 | /// struct Foo(i32, String); |
313 | /// |
314 | /// impl fmt::Debug for Foo { |
315 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
316 | /// fmt.debug_tuple("Foo" ) |
317 | /// .field(&self.0) // We add the first field. |
318 | /// .field(&self.1) // We add the second field. |
319 | /// .finish() // We're good to go! |
320 | /// } |
321 | /// } |
322 | /// |
323 | /// assert_eq!( |
324 | /// format!("{:?}" , Foo(10, "Hello World" .to_string())), |
325 | /// r#"Foo(10, "Hello World")"# , |
326 | /// ); |
327 | /// ``` |
328 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
329 | pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut Self { |
330 | self.field_with(|f| value.fmt(f)) |
331 | } |
332 | |
333 | /// Adds a new field to the generated tuple struct output. |
334 | /// |
335 | /// This method is equivalent to [`DebugTuple::field`], but formats the |
336 | /// value using a provided closure rather than by calling [`Debug::fmt`]. |
337 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
338 | pub fn field_with<F>(&mut self, value_fmt: F) -> &mut Self |
339 | where |
340 | F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, |
341 | { |
342 | self.result = self.result.and_then(|_| { |
343 | if self.is_pretty() { |
344 | if self.fields == 0 { |
345 | self.fmt.write_str("( \n" )?; |
346 | } |
347 | let mut slot = None; |
348 | let mut state = Default::default(); |
349 | let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state); |
350 | value_fmt(&mut writer)?; |
351 | writer.write_str(", \n" ) |
352 | } else { |
353 | let prefix = if self.fields == 0 { "(" } else { ", " }; |
354 | self.fmt.write_str(prefix)?; |
355 | value_fmt(self.fmt) |
356 | } |
357 | }); |
358 | |
359 | self.fields += 1; |
360 | self |
361 | } |
362 | |
363 | /// Marks the tuple struct as non-exhaustive, indicating to the reader that there are some |
364 | /// other fields that are not shown in the debug representation. |
365 | /// |
366 | /// # Examples |
367 | /// |
368 | /// ``` |
369 | /// use std::fmt; |
370 | /// |
371 | /// struct Foo(i32, String); |
372 | /// |
373 | /// impl fmt::Debug for Foo { |
374 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
375 | /// fmt.debug_tuple("Foo" ) |
376 | /// .field(&self.0) |
377 | /// .finish_non_exhaustive() // Show that some other field(s) exist. |
378 | /// } |
379 | /// } |
380 | /// |
381 | /// assert_eq!( |
382 | /// format!("{:?}" , Foo(10, "secret!" .to_owned())), |
383 | /// "Foo(10, ..)" , |
384 | /// ); |
385 | /// ``` |
386 | #[stable (feature = "debug_more_non_exhaustive" , since = "1.83.0" )] |
387 | pub fn finish_non_exhaustive(&mut self) -> fmt::Result { |
388 | self.result = self.result.and_then(|_| { |
389 | if self.fields > 0 { |
390 | if self.is_pretty() { |
391 | let mut slot = None; |
392 | let mut state = Default::default(); |
393 | let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state); |
394 | writer.write_str(".. \n" )?; |
395 | self.fmt.write_str(")" ) |
396 | } else { |
397 | self.fmt.write_str(", ..)" ) |
398 | } |
399 | } else { |
400 | self.fmt.write_str("(..)" ) |
401 | } |
402 | }); |
403 | self.result |
404 | } |
405 | |
406 | /// Finishes output and returns any error encountered. |
407 | /// |
408 | /// # Examples |
409 | /// |
410 | /// ``` |
411 | /// use std::fmt; |
412 | /// |
413 | /// struct Foo(i32, String); |
414 | /// |
415 | /// impl fmt::Debug for Foo { |
416 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
417 | /// fmt.debug_tuple("Foo" ) |
418 | /// .field(&self.0) |
419 | /// .field(&self.1) |
420 | /// .finish() // You need to call it to "finish" the |
421 | /// // tuple formatting. |
422 | /// } |
423 | /// } |
424 | /// |
425 | /// assert_eq!( |
426 | /// format!("{:?}" , Foo(10, "Hello World" .to_string())), |
427 | /// r#"Foo(10, "Hello World")"# , |
428 | /// ); |
429 | /// ``` |
430 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
431 | pub fn finish(&mut self) -> fmt::Result { |
432 | if self.fields > 0 { |
433 | self.result = self.result.and_then(|_| { |
434 | if self.fields == 1 && self.empty_name && !self.is_pretty() { |
435 | self.fmt.write_str("," )?; |
436 | } |
437 | self.fmt.write_str(")" ) |
438 | }); |
439 | } |
440 | self.result |
441 | } |
442 | |
443 | fn is_pretty(&self) -> bool { |
444 | self.fmt.alternate() |
445 | } |
446 | } |
447 | |
448 | /// A helper used to print list-like items with no special formatting. |
449 | struct DebugInner<'a, 'b: 'a> { |
450 | fmt: &'a mut fmt::Formatter<'b>, |
451 | result: fmt::Result, |
452 | has_fields: bool, |
453 | } |
454 | |
455 | impl<'a, 'b: 'a> DebugInner<'a, 'b> { |
456 | fn entry_with<F>(&mut self, entry_fmt: F) |
457 | where |
458 | F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, |
459 | { |
460 | self.result = self.result.and_then(|_| { |
461 | if self.is_pretty() { |
462 | if !self.has_fields { |
463 | self.fmt.write_str(" \n" )?; |
464 | } |
465 | let mut slot = None; |
466 | let mut state = Default::default(); |
467 | let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state); |
468 | entry_fmt(&mut writer)?; |
469 | writer.write_str(", \n" ) |
470 | } else { |
471 | if self.has_fields { |
472 | self.fmt.write_str(", " )? |
473 | } |
474 | entry_fmt(self.fmt) |
475 | } |
476 | }); |
477 | |
478 | self.has_fields = true; |
479 | } |
480 | |
481 | fn is_pretty(&self) -> bool { |
482 | self.fmt.alternate() |
483 | } |
484 | } |
485 | |
486 | /// A struct to help with [`fmt::Debug`](Debug) implementations. |
487 | /// |
488 | /// This is useful when you wish to output a formatted set of items as a part |
489 | /// of your [`Debug::fmt`] implementation. |
490 | /// |
491 | /// This can be constructed by the [`Formatter::debug_set`] method. |
492 | /// |
493 | /// # Examples |
494 | /// |
495 | /// ``` |
496 | /// use std::fmt; |
497 | /// |
498 | /// struct Foo(Vec<i32>); |
499 | /// |
500 | /// impl fmt::Debug for Foo { |
501 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
502 | /// fmt.debug_set().entries(self.0.iter()).finish() |
503 | /// } |
504 | /// } |
505 | /// |
506 | /// assert_eq!( |
507 | /// format!("{:?}" , Foo(vec![10, 11])), |
508 | /// "{10, 11}" , |
509 | /// ); |
510 | /// ``` |
511 | #[must_use = "must eventually call `finish()` on Debug builders" ] |
512 | #[allow (missing_debug_implementations)] |
513 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
514 | pub struct DebugSet<'a, 'b: 'a> { |
515 | inner: DebugInner<'a, 'b>, |
516 | } |
517 | |
518 | pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> { |
519 | let result: Result<(), Error> = fmt.write_str(data:"{" ); |
520 | DebugSet { inner: DebugInner { fmt, result, has_fields: false } } |
521 | } |
522 | |
523 | impl<'a, 'b: 'a> DebugSet<'a, 'b> { |
524 | /// Adds a new entry to the set output. |
525 | /// |
526 | /// # Examples |
527 | /// |
528 | /// ``` |
529 | /// use std::fmt; |
530 | /// |
531 | /// struct Foo(Vec<i32>, Vec<u32>); |
532 | /// |
533 | /// impl fmt::Debug for Foo { |
534 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
535 | /// fmt.debug_set() |
536 | /// .entry(&self.0) // Adds the first "entry". |
537 | /// .entry(&self.1) // Adds the second "entry". |
538 | /// .finish() |
539 | /// } |
540 | /// } |
541 | /// |
542 | /// assert_eq!( |
543 | /// format!("{:?}" , Foo(vec![10, 11], vec![12, 13])), |
544 | /// "{[10, 11], [12, 13]}" , |
545 | /// ); |
546 | /// ``` |
547 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
548 | pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self { |
549 | self.inner.entry_with(|f| entry.fmt(f)); |
550 | self |
551 | } |
552 | |
553 | /// Adds a new entry to the set output. |
554 | /// |
555 | /// This method is equivalent to [`DebugSet::entry`], but formats the |
556 | /// entry using a provided closure rather than by calling [`Debug::fmt`]. |
557 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
558 | pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self |
559 | where |
560 | F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, |
561 | { |
562 | self.inner.entry_with(entry_fmt); |
563 | self |
564 | } |
565 | |
566 | /// Adds the contents of an iterator of entries to the set output. |
567 | /// |
568 | /// # Examples |
569 | /// |
570 | /// ``` |
571 | /// use std::fmt; |
572 | /// |
573 | /// struct Foo(Vec<i32>, Vec<u32>); |
574 | /// |
575 | /// impl fmt::Debug for Foo { |
576 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
577 | /// fmt.debug_set() |
578 | /// .entries(self.0.iter()) // Adds the first "entry". |
579 | /// .entries(self.1.iter()) // Adds the second "entry". |
580 | /// .finish() |
581 | /// } |
582 | /// } |
583 | /// |
584 | /// assert_eq!( |
585 | /// format!("{:?}" , Foo(vec![10, 11], vec![12, 13])), |
586 | /// "{10, 11, 12, 13}" , |
587 | /// ); |
588 | /// ``` |
589 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
590 | pub fn entries<D, I>(&mut self, entries: I) -> &mut Self |
591 | where |
592 | D: fmt::Debug, |
593 | I: IntoIterator<Item = D>, |
594 | { |
595 | for entry in entries { |
596 | self.entry(&entry); |
597 | } |
598 | self |
599 | } |
600 | |
601 | /// Marks the set as non-exhaustive, indicating to the reader that there are some other |
602 | /// elements that are not shown in the debug representation. |
603 | /// |
604 | /// # Examples |
605 | /// |
606 | /// ``` |
607 | /// use std::fmt; |
608 | /// |
609 | /// struct Foo(Vec<i32>); |
610 | /// |
611 | /// impl fmt::Debug for Foo { |
612 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
613 | /// // Print at most two elements, abbreviate the rest |
614 | /// let mut f = fmt.debug_set(); |
615 | /// let mut f = f.entries(self.0.iter().take(2)); |
616 | /// if self.0.len() > 2 { |
617 | /// f.finish_non_exhaustive() |
618 | /// } else { |
619 | /// f.finish() |
620 | /// } |
621 | /// } |
622 | /// } |
623 | /// |
624 | /// assert_eq!( |
625 | /// format!("{:?}" , Foo(vec![1, 2, 3, 4])), |
626 | /// "{1, 2, ..}" , |
627 | /// ); |
628 | /// ``` |
629 | #[stable (feature = "debug_more_non_exhaustive" , since = "1.83.0" )] |
630 | pub fn finish_non_exhaustive(&mut self) -> fmt::Result { |
631 | self.inner.result = self.inner.result.and_then(|_| { |
632 | if self.inner.has_fields { |
633 | if self.inner.is_pretty() { |
634 | let mut slot = None; |
635 | let mut state = Default::default(); |
636 | let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state); |
637 | writer.write_str(".. \n" )?; |
638 | self.inner.fmt.write_str("}" ) |
639 | } else { |
640 | self.inner.fmt.write_str(", ..}" ) |
641 | } |
642 | } else { |
643 | self.inner.fmt.write_str("..}" ) |
644 | } |
645 | }); |
646 | self.inner.result |
647 | } |
648 | |
649 | /// Finishes output and returns any error encountered. |
650 | /// |
651 | /// # Examples |
652 | /// |
653 | /// ``` |
654 | /// use std::fmt; |
655 | /// |
656 | /// struct Foo(Vec<i32>); |
657 | /// |
658 | /// impl fmt::Debug for Foo { |
659 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
660 | /// fmt.debug_set() |
661 | /// .entries(self.0.iter()) |
662 | /// .finish() // Ends the set formatting. |
663 | /// } |
664 | /// } |
665 | /// |
666 | /// assert_eq!( |
667 | /// format!("{:?}" , Foo(vec![10, 11])), |
668 | /// "{10, 11}" , |
669 | /// ); |
670 | /// ``` |
671 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
672 | pub fn finish(&mut self) -> fmt::Result { |
673 | self.inner.result = self.inner.result.and_then(|_| self.inner.fmt.write_str("}" )); |
674 | self.inner.result |
675 | } |
676 | } |
677 | |
678 | /// A struct to help with [`fmt::Debug`](Debug) implementations. |
679 | /// |
680 | /// This is useful when you wish to output a formatted list of items as a part |
681 | /// of your [`Debug::fmt`] implementation. |
682 | /// |
683 | /// This can be constructed by the [`Formatter::debug_list`] method. |
684 | /// |
685 | /// # Examples |
686 | /// |
687 | /// ``` |
688 | /// use std::fmt; |
689 | /// |
690 | /// struct Foo(Vec<i32>); |
691 | /// |
692 | /// impl fmt::Debug for Foo { |
693 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
694 | /// fmt.debug_list().entries(self.0.iter()).finish() |
695 | /// } |
696 | /// } |
697 | /// |
698 | /// assert_eq!( |
699 | /// format!("{:?}" , Foo(vec![10, 11])), |
700 | /// "[10, 11]" , |
701 | /// ); |
702 | /// ``` |
703 | #[must_use = "must eventually call `finish()` on Debug builders" ] |
704 | #[allow (missing_debug_implementations)] |
705 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
706 | pub struct DebugList<'a, 'b: 'a> { |
707 | inner: DebugInner<'a, 'b>, |
708 | } |
709 | |
710 | pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> { |
711 | let result: Result<(), Error> = fmt.write_str(data:"[" ); |
712 | DebugList { inner: DebugInner { fmt, result, has_fields: false } } |
713 | } |
714 | |
715 | impl<'a, 'b: 'a> DebugList<'a, 'b> { |
716 | /// Adds a new entry to the list output. |
717 | /// |
718 | /// # Examples |
719 | /// |
720 | /// ``` |
721 | /// use std::fmt; |
722 | /// |
723 | /// struct Foo(Vec<i32>, Vec<u32>); |
724 | /// |
725 | /// impl fmt::Debug for Foo { |
726 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
727 | /// fmt.debug_list() |
728 | /// .entry(&self.0) // We add the first "entry". |
729 | /// .entry(&self.1) // We add the second "entry". |
730 | /// .finish() |
731 | /// } |
732 | /// } |
733 | /// |
734 | /// assert_eq!( |
735 | /// format!("{:?}" , Foo(vec![10, 11], vec![12, 13])), |
736 | /// "[[10, 11], [12, 13]]" , |
737 | /// ); |
738 | /// ``` |
739 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
740 | pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self { |
741 | self.inner.entry_with(|f| entry.fmt(f)); |
742 | self |
743 | } |
744 | |
745 | /// Adds a new entry to the list output. |
746 | /// |
747 | /// This method is equivalent to [`DebugList::entry`], but formats the |
748 | /// entry using a provided closure rather than by calling [`Debug::fmt`]. |
749 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
750 | pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self |
751 | where |
752 | F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, |
753 | { |
754 | self.inner.entry_with(entry_fmt); |
755 | self |
756 | } |
757 | |
758 | /// Adds the contents of an iterator of entries to the list output. |
759 | /// |
760 | /// # Examples |
761 | /// |
762 | /// ``` |
763 | /// use std::fmt; |
764 | /// |
765 | /// struct Foo(Vec<i32>, Vec<u32>); |
766 | /// |
767 | /// impl fmt::Debug for Foo { |
768 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
769 | /// fmt.debug_list() |
770 | /// .entries(self.0.iter()) |
771 | /// .entries(self.1.iter()) |
772 | /// .finish() |
773 | /// } |
774 | /// } |
775 | /// |
776 | /// assert_eq!( |
777 | /// format!("{:?}" , Foo(vec![10, 11], vec![12, 13])), |
778 | /// "[10, 11, 12, 13]" , |
779 | /// ); |
780 | /// ``` |
781 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
782 | pub fn entries<D, I>(&mut self, entries: I) -> &mut Self |
783 | where |
784 | D: fmt::Debug, |
785 | I: IntoIterator<Item = D>, |
786 | { |
787 | for entry in entries { |
788 | self.entry(&entry); |
789 | } |
790 | self |
791 | } |
792 | |
793 | /// Marks the list as non-exhaustive, indicating to the reader that there are some other |
794 | /// elements that are not shown in the debug representation. |
795 | /// |
796 | /// # Examples |
797 | /// |
798 | /// ``` |
799 | /// use std::fmt; |
800 | /// |
801 | /// struct Foo(Vec<i32>); |
802 | /// |
803 | /// impl fmt::Debug for Foo { |
804 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
805 | /// // Print at most two elements, abbreviate the rest |
806 | /// let mut f = fmt.debug_list(); |
807 | /// let mut f = f.entries(self.0.iter().take(2)); |
808 | /// if self.0.len() > 2 { |
809 | /// f.finish_non_exhaustive() |
810 | /// } else { |
811 | /// f.finish() |
812 | /// } |
813 | /// } |
814 | /// } |
815 | /// |
816 | /// assert_eq!( |
817 | /// format!("{:?}" , Foo(vec![1, 2, 3, 4])), |
818 | /// "[1, 2, ..]" , |
819 | /// ); |
820 | /// ``` |
821 | #[stable (feature = "debug_more_non_exhaustive" , since = "1.83.0" )] |
822 | pub fn finish_non_exhaustive(&mut self) -> fmt::Result { |
823 | self.inner.result.and_then(|_| { |
824 | if self.inner.has_fields { |
825 | if self.inner.is_pretty() { |
826 | let mut slot = None; |
827 | let mut state = Default::default(); |
828 | let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state); |
829 | writer.write_str(".. \n" )?; |
830 | self.inner.fmt.write_str("]" ) |
831 | } else { |
832 | self.inner.fmt.write_str(", ..]" ) |
833 | } |
834 | } else { |
835 | self.inner.fmt.write_str("..]" ) |
836 | } |
837 | }) |
838 | } |
839 | |
840 | /// Finishes output and returns any error encountered. |
841 | /// |
842 | /// # Examples |
843 | /// |
844 | /// ``` |
845 | /// use std::fmt; |
846 | /// |
847 | /// struct Foo(Vec<i32>); |
848 | /// |
849 | /// impl fmt::Debug for Foo { |
850 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
851 | /// fmt.debug_list() |
852 | /// .entries(self.0.iter()) |
853 | /// .finish() // Ends the list formatting. |
854 | /// } |
855 | /// } |
856 | /// |
857 | /// assert_eq!( |
858 | /// format!("{:?}" , Foo(vec![10, 11])), |
859 | /// "[10, 11]" , |
860 | /// ); |
861 | /// ``` |
862 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
863 | pub fn finish(&mut self) -> fmt::Result { |
864 | self.inner.result = self.inner.result.and_then(|_| self.inner.fmt.write_str("]" )); |
865 | self.inner.result |
866 | } |
867 | } |
868 | |
869 | /// A struct to help with [`fmt::Debug`](Debug) implementations. |
870 | /// |
871 | /// This is useful when you wish to output a formatted map as a part of your |
872 | /// [`Debug::fmt`] implementation. |
873 | /// |
874 | /// This can be constructed by the [`Formatter::debug_map`] method. |
875 | /// |
876 | /// # Examples |
877 | /// |
878 | /// ``` |
879 | /// use std::fmt; |
880 | /// |
881 | /// struct Foo(Vec<(String, i32)>); |
882 | /// |
883 | /// impl fmt::Debug for Foo { |
884 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
885 | /// fmt.debug_map().entries(self.0.iter().map(|&(ref k, ref v)| (k, v))).finish() |
886 | /// } |
887 | /// } |
888 | /// |
889 | /// assert_eq!( |
890 | /// format!("{:?}" , Foo(vec![("A" .to_string(), 10), ("B" .to_string(), 11)])), |
891 | /// r#"{"A": 10, "B": 11}"# , |
892 | /// ); |
893 | /// ``` |
894 | #[must_use = "must eventually call `finish()` on Debug builders" ] |
895 | #[allow (missing_debug_implementations)] |
896 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
897 | pub struct DebugMap<'a, 'b: 'a> { |
898 | fmt: &'a mut fmt::Formatter<'b>, |
899 | result: fmt::Result, |
900 | has_fields: bool, |
901 | has_key: bool, |
902 | // The state of newlines is tracked between keys and values |
903 | state: PadAdapterState, |
904 | } |
905 | |
906 | pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> { |
907 | let result: Result<(), Error> = fmt.write_str(data:"{" ); |
908 | DebugMap { fmt, result, has_fields: false, has_key: false, state: Default::default() } |
909 | } |
910 | |
911 | impl<'a, 'b: 'a> DebugMap<'a, 'b> { |
912 | /// Adds a new entry to the map output. |
913 | /// |
914 | /// # Examples |
915 | /// |
916 | /// ``` |
917 | /// use std::fmt; |
918 | /// |
919 | /// struct Foo(Vec<(String, i32)>); |
920 | /// |
921 | /// impl fmt::Debug for Foo { |
922 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
923 | /// fmt.debug_map() |
924 | /// .entry(&"whole" , &self.0) // We add the "whole" entry. |
925 | /// .finish() |
926 | /// } |
927 | /// } |
928 | /// |
929 | /// assert_eq!( |
930 | /// format!("{:?}" , Foo(vec![("A" .to_string(), 10), ("B" .to_string(), 11)])), |
931 | /// r#"{"whole": [("A", 10), ("B", 11)]}"# , |
932 | /// ); |
933 | /// ``` |
934 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
935 | pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut Self { |
936 | self.key(key).value(value) |
937 | } |
938 | |
939 | /// Adds the key part of a new entry to the map output. |
940 | /// |
941 | /// This method, together with `value`, is an alternative to `entry` that |
942 | /// can be used when the complete entry isn't known upfront. Prefer the `entry` |
943 | /// method when it's possible to use. |
944 | /// |
945 | /// # Panics |
946 | /// |
947 | /// `key` must be called before `value` and each call to `key` must be followed |
948 | /// by a corresponding call to `value`. Otherwise this method will panic. |
949 | /// |
950 | /// # Examples |
951 | /// |
952 | /// ``` |
953 | /// use std::fmt; |
954 | /// |
955 | /// struct Foo(Vec<(String, i32)>); |
956 | /// |
957 | /// impl fmt::Debug for Foo { |
958 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
959 | /// fmt.debug_map() |
960 | /// .key(&"whole" ).value(&self.0) // We add the "whole" entry. |
961 | /// .finish() |
962 | /// } |
963 | /// } |
964 | /// |
965 | /// assert_eq!( |
966 | /// format!("{:?}" , Foo(vec![("A" .to_string(), 10), ("B" .to_string(), 11)])), |
967 | /// r#"{"whole": [("A", 10), ("B", 11)]}"# , |
968 | /// ); |
969 | /// ``` |
970 | #[stable (feature = "debug_map_key_value" , since = "1.42.0" )] |
971 | pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut Self { |
972 | self.key_with(|f| key.fmt(f)) |
973 | } |
974 | |
975 | /// Adds the key part of a new entry to the map output. |
976 | /// |
977 | /// This method is equivalent to [`DebugMap::key`], but formats the |
978 | /// key using a provided closure rather than by calling [`Debug::fmt`]. |
979 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
980 | pub fn key_with<F>(&mut self, key_fmt: F) -> &mut Self |
981 | where |
982 | F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, |
983 | { |
984 | self.result = self.result.and_then(|_| { |
985 | assert!( |
986 | !self.has_key, |
987 | "attempted to begin a new map entry \ |
988 | without completing the previous one" |
989 | ); |
990 | |
991 | if self.is_pretty() { |
992 | if !self.has_fields { |
993 | self.fmt.write_str(" \n" )?; |
994 | } |
995 | let mut slot = None; |
996 | self.state = Default::default(); |
997 | let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state); |
998 | key_fmt(&mut writer)?; |
999 | writer.write_str(": " )?; |
1000 | } else { |
1001 | if self.has_fields { |
1002 | self.fmt.write_str(", " )? |
1003 | } |
1004 | key_fmt(self.fmt)?; |
1005 | self.fmt.write_str(": " )?; |
1006 | } |
1007 | |
1008 | self.has_key = true; |
1009 | Ok(()) |
1010 | }); |
1011 | |
1012 | self |
1013 | } |
1014 | |
1015 | /// Adds the value part of a new entry to the map output. |
1016 | /// |
1017 | /// This method, together with `key`, is an alternative to `entry` that |
1018 | /// can be used when the complete entry isn't known upfront. Prefer the `entry` |
1019 | /// method when it's possible to use. |
1020 | /// |
1021 | /// # Panics |
1022 | /// |
1023 | /// `key` must be called before `value` and each call to `key` must be followed |
1024 | /// by a corresponding call to `value`. Otherwise this method will panic. |
1025 | /// |
1026 | /// # Examples |
1027 | /// |
1028 | /// ``` |
1029 | /// use std::fmt; |
1030 | /// |
1031 | /// struct Foo(Vec<(String, i32)>); |
1032 | /// |
1033 | /// impl fmt::Debug for Foo { |
1034 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
1035 | /// fmt.debug_map() |
1036 | /// .key(&"whole" ).value(&self.0) // We add the "whole" entry. |
1037 | /// .finish() |
1038 | /// } |
1039 | /// } |
1040 | /// |
1041 | /// assert_eq!( |
1042 | /// format!("{:?}" , Foo(vec![("A" .to_string(), 10), ("B" .to_string(), 11)])), |
1043 | /// r#"{"whole": [("A", 10), ("B", 11)]}"# , |
1044 | /// ); |
1045 | /// ``` |
1046 | #[stable (feature = "debug_map_key_value" , since = "1.42.0" )] |
1047 | pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut Self { |
1048 | self.value_with(|f| value.fmt(f)) |
1049 | } |
1050 | |
1051 | /// Adds the value part of a new entry to the map output. |
1052 | /// |
1053 | /// This method is equivalent to [`DebugMap::value`], but formats the |
1054 | /// value using a provided closure rather than by calling [`Debug::fmt`]. |
1055 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
1056 | pub fn value_with<F>(&mut self, value_fmt: F) -> &mut Self |
1057 | where |
1058 | F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, |
1059 | { |
1060 | self.result = self.result.and_then(|_| { |
1061 | assert!(self.has_key, "attempted to format a map value before its key" ); |
1062 | |
1063 | if self.is_pretty() { |
1064 | let mut slot = None; |
1065 | let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state); |
1066 | value_fmt(&mut writer)?; |
1067 | writer.write_str(", \n" )?; |
1068 | } else { |
1069 | value_fmt(self.fmt)?; |
1070 | } |
1071 | |
1072 | self.has_key = false; |
1073 | Ok(()) |
1074 | }); |
1075 | |
1076 | self.has_fields = true; |
1077 | self |
1078 | } |
1079 | |
1080 | /// Adds the contents of an iterator of entries to the map output. |
1081 | /// |
1082 | /// # Examples |
1083 | /// |
1084 | /// ``` |
1085 | /// use std::fmt; |
1086 | /// |
1087 | /// struct Foo(Vec<(String, i32)>); |
1088 | /// |
1089 | /// impl fmt::Debug for Foo { |
1090 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
1091 | /// fmt.debug_map() |
1092 | /// // We map our vec so each entries' first field will become |
1093 | /// // the "key". |
1094 | /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v))) |
1095 | /// .finish() |
1096 | /// } |
1097 | /// } |
1098 | /// |
1099 | /// assert_eq!( |
1100 | /// format!("{:?}" , Foo(vec![("A" .to_string(), 10), ("B" .to_string(), 11)])), |
1101 | /// r#"{"A": 10, "B": 11}"# , |
1102 | /// ); |
1103 | /// ``` |
1104 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
1105 | pub fn entries<K, V, I>(&mut self, entries: I) -> &mut Self |
1106 | where |
1107 | K: fmt::Debug, |
1108 | V: fmt::Debug, |
1109 | I: IntoIterator<Item = (K, V)>, |
1110 | { |
1111 | for (k, v) in entries { |
1112 | self.entry(&k, &v); |
1113 | } |
1114 | self |
1115 | } |
1116 | |
1117 | /// Marks the map as non-exhaustive, indicating to the reader that there are some other |
1118 | /// entries that are not shown in the debug representation. |
1119 | /// |
1120 | /// # Examples |
1121 | /// |
1122 | /// ``` |
1123 | /// use std::fmt; |
1124 | /// |
1125 | /// struct Foo(Vec<(String, i32)>); |
1126 | /// |
1127 | /// impl fmt::Debug for Foo { |
1128 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
1129 | /// // Print at most two elements, abbreviate the rest |
1130 | /// let mut f = fmt.debug_map(); |
1131 | /// let mut f = f.entries(self.0.iter().take(2).map(|&(ref k, ref v)| (k, v))); |
1132 | /// if self.0.len() > 2 { |
1133 | /// f.finish_non_exhaustive() |
1134 | /// } else { |
1135 | /// f.finish() |
1136 | /// } |
1137 | /// } |
1138 | /// } |
1139 | /// |
1140 | /// assert_eq!( |
1141 | /// format!("{:?}" , Foo(vec![ |
1142 | /// ("A" .to_string(), 10), |
1143 | /// ("B" .to_string(), 11), |
1144 | /// ("C" .to_string(), 12), |
1145 | /// ])), |
1146 | /// r#"{"A": 10, "B": 11, ..}"# , |
1147 | /// ); |
1148 | /// ``` |
1149 | #[stable (feature = "debug_more_non_exhaustive" , since = "1.83.0" )] |
1150 | pub fn finish_non_exhaustive(&mut self) -> fmt::Result { |
1151 | self.result = self.result.and_then(|_| { |
1152 | assert!(!self.has_key, "attempted to finish a map with a partial entry" ); |
1153 | |
1154 | if self.has_fields { |
1155 | if self.is_pretty() { |
1156 | let mut slot = None; |
1157 | let mut state = Default::default(); |
1158 | let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state); |
1159 | writer.write_str(".. \n" )?; |
1160 | self.fmt.write_str("}" ) |
1161 | } else { |
1162 | self.fmt.write_str(", ..}" ) |
1163 | } |
1164 | } else { |
1165 | self.fmt.write_str("..}" ) |
1166 | } |
1167 | }); |
1168 | self.result |
1169 | } |
1170 | |
1171 | /// Finishes output and returns any error encountered. |
1172 | /// |
1173 | /// # Panics |
1174 | /// |
1175 | /// `key` must be called before `value` and each call to `key` must be followed |
1176 | /// by a corresponding call to `value`. Otherwise this method will panic. |
1177 | /// |
1178 | /// # Examples |
1179 | /// |
1180 | /// ``` |
1181 | /// use std::fmt; |
1182 | /// |
1183 | /// struct Foo(Vec<(String, i32)>); |
1184 | /// |
1185 | /// impl fmt::Debug for Foo { |
1186 | /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
1187 | /// fmt.debug_map() |
1188 | /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v))) |
1189 | /// .finish() // Ends the map formatting. |
1190 | /// } |
1191 | /// } |
1192 | /// |
1193 | /// assert_eq!( |
1194 | /// format!("{:?}" , Foo(vec![("A" .to_string(), 10), ("B" .to_string(), 11)])), |
1195 | /// r#"{"A": 10, "B": 11}"# , |
1196 | /// ); |
1197 | /// ``` |
1198 | #[stable (feature = "debug_builders" , since = "1.2.0" )] |
1199 | pub fn finish(&mut self) -> fmt::Result { |
1200 | self.result = self.result.and_then(|_| { |
1201 | assert!(!self.has_key, "attempted to finish a map with a partial entry" ); |
1202 | |
1203 | self.fmt.write_str("}" ) |
1204 | }); |
1205 | self.result |
1206 | } |
1207 | |
1208 | fn is_pretty(&self) -> bool { |
1209 | self.fmt.alternate() |
1210 | } |
1211 | } |
1212 | |
1213 | /// Creates a type whose [`fmt::Debug`] and [`fmt::Display`] impls are provided with the function |
1214 | /// `f`. |
1215 | /// |
1216 | /// # Examples |
1217 | /// |
1218 | /// ``` |
1219 | /// #![feature(debug_closure_helpers)] |
1220 | /// use std::fmt; |
1221 | /// |
1222 | /// let value = 'a' ; |
1223 | /// assert_eq!(format!("{}" , value), "a" ); |
1224 | /// assert_eq!(format!("{:?}" , value), "'a'" ); |
1225 | /// |
1226 | /// let wrapped = fmt::from_fn(|f| write!(f, "{value:?}" )); |
1227 | /// assert_eq!(format!("{}" , wrapped), "'a'" ); |
1228 | /// assert_eq!(format!("{:?}" , wrapped), "'a'" ); |
1229 | /// ``` |
1230 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
1231 | #[must_use = "returns a type implementing Debug and Display, which do not have any effects unless they are used" ] |
1232 | pub fn from_fn<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result>(f: F) -> FromFn<F> { |
1233 | FromFn(f) |
1234 | } |
1235 | |
1236 | /// Implements [`fmt::Debug`] and [`fmt::Display`] using a function. |
1237 | /// |
1238 | /// Created with [`from_fn`]. |
1239 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
1240 | pub struct FromFn<F>(F) |
1241 | where |
1242 | F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result; |
1243 | |
1244 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
1245 | impl<F> fmt::Debug for FromFn<F> |
1246 | where |
1247 | F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, |
1248 | { |
1249 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1250 | (self.0)(f) |
1251 | } |
1252 | } |
1253 | |
1254 | #[unstable (feature = "debug_closure_helpers" , issue = "117729" )] |
1255 | impl<F> fmt::Display for FromFn<F> |
1256 | where |
1257 | F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, |
1258 | { |
1259 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1260 | (self.0)(f) |
1261 | } |
1262 | } |
1263 | |