1use std::{
2 alloc::Layout,
3 collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque},
4 num::IntErrorKind,
5 ops::Deref,
6 path::{Path, PathBuf},
7 rc::Rc,
8 sync::{Arc, Mutex, TryLockError},
9};
10
11use crate::{Debug, Formatter};
12
13macro_rules! std_debug {
14 ($($t:ty),+ ,) => {
15 $(
16 impl Debug for $t {
17 fn fmt(&self, f: &mut Formatter) {
18 f.write_debug(self)
19 }
20 }
21 )+
22 };
23}
24
25std_debug! {
26 bool,
27 char,
28 f32,
29 f64,
30 isize,
31 i8,
32 i16,
33 i32,
34 i64,
35 i128,
36 usize,
37 u8,
38 u16,
39 u32,
40 u64,
41 u128,
42 String,
43 str,
44 (),
45 Path,
46 PathBuf,
47 std::num::NonZeroI8,
48 std::num::NonZeroI16,
49 std::num::NonZeroI32,
50 std::num::NonZeroI64,
51 std::num::NonZeroI128,
52 std::num::NonZeroIsize,
53 std::num::NonZeroU8,
54 std::num::NonZeroU16,
55 std::num::NonZeroU32,
56 std::num::NonZeroU64,
57 std::num::NonZeroU128,
58 std::num::NonZeroUsize,
59}
60
61macro_rules! peel {
62 ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* })
63}
64
65macro_rules! tuple {
66 () => ();
67 ( $($name:ident,)+ ) => (
68 impl<$($name:Debug),+> Debug for ($($name,)+) where last_type!($($name,)+): ?Sized {
69 #[allow(non_snake_case, unused_assignments)]
70 fn fmt(&self, f: &mut Formatter) {
71 let mut builder = f.debug_tuple("");
72 let ($(ref $name,)+) = *self;
73 $(
74 builder.field(&$name);
75 )+
76
77 builder.finish()
78 }
79 }
80 peel! { $($name,)+ }
81 )
82}
83
84macro_rules! last_type {
85 ($a:ident,) => { $a };
86 ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
87}
88
89tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
90
91macro_rules! fmt_refs {
92 ($($tr:ident),*) => {
93 $(
94 impl<T: ?Sized + $tr> $tr for &T {
95 fn fmt(&self, f: &mut Formatter) { $tr::fmt(&**self, f) }
96 }
97 impl<T: ?Sized + $tr> $tr for &mut T {
98 fn fmt(&self, f: &mut Formatter) { $tr::fmt(&**self, f) }
99 }
100 )*
101 }
102}
103
104fmt_refs! { Debug }
105
106impl<T: ?Sized + Debug> Debug for Box<T> {
107 fn fmt(&self, f: &mut Formatter) {
108 Debug::fmt(&**self, f)
109 }
110}
111
112impl<T: Debug, const N: usize> Debug for [T; N] {
113 fn fmt(&self, f: &mut Formatter) {
114 Debug::fmt(&self[..], f)
115 }
116}
117
118impl<T: ?Sized + Debug> Debug for Arc<T> {
119 fn fmt(&self, f: &mut Formatter) {
120 Debug::fmt(&**self, f)
121 }
122}
123
124impl<T: ?Sized + Debug> Debug for Rc<T> {
125 fn fmt(&self, f: &mut Formatter) {
126 Debug::fmt(&**self, f)
127 }
128}
129
130impl<T: ?Sized> Debug for *const T {
131 fn fmt(&self, f: &mut Formatter) {
132 f.write_debug(self)
133 }
134}
135
136impl<T: ?Sized> Debug for *mut T {
137 fn fmt(&self, f: &mut Formatter) {
138 Debug::fmt(&(self as *const _), f)
139 }
140}
141
142macro_rules! list_like {
143 ($($t:ty),+) => {
144 $(
145 impl<T: Debug> Debug for $t {
146 fn fmt(&self, f: &mut Formatter) {
147 f.debug_list().entries(self.iter()).finish()
148 }
149 }
150 )+
151 };
152}
153
154list_like! {
155 [T], Vec<T>, VecDeque<T>, LinkedList<T>, BinaryHeap<T>
156}
157
158impl<K, V, S> Debug for HashMap<K, V, S>
159where
160 K: Debug,
161 V: Debug,
162{
163 fn fmt(&self, f: &mut Formatter) {
164 f.debug_map().entries(self.iter()).finish()
165 }
166}
167impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
168 fn fmt(&self, f: &mut Formatter) {
169 f.debug_map().entries(self.iter()).finish()
170 }
171}
172impl<T, S> Debug for HashSet<T, S>
173where
174 T: Debug,
175{
176 fn fmt(&self, f: &mut Formatter) {
177 f.debug_set().entries(self.iter()).finish()
178 }
179}
180impl<T> Debug for BTreeSet<T>
181where
182 T: Debug,
183{
184 fn fmt(&self, f: &mut Formatter) {
185 f.debug_set().entries(self.iter()).finish()
186 }
187}
188impl<T: Debug> Debug for Option<T> {
189 fn fmt(&self, f: &mut Formatter) {
190 match self {
191 Some(v) => f.debug_tuple("Some").field(v).finish(),
192 None => f.debug_tuple("None").finish(),
193 }
194 }
195}
196
197impl<T: ?Sized> Debug for std::marker::PhantomData<T> {
198 fn fmt(&self, f: &mut Formatter) {
199 f.debug_struct("PhantomData").finish()
200 }
201}
202
203impl<T: Copy + Debug> Debug for std::cell::Cell<T> {
204 fn fmt(&self, f: &mut Formatter) {
205 f.debug_struct("Cell").field("value", &self.get()).finish()
206 }
207}
208
209impl<T: ?Sized + Debug> Debug for std::cell::RefCell<T> {
210 fn fmt(&self, f: &mut Formatter) {
211 match self.try_borrow() {
212 Ok(borrow) => f.debug_struct("RefCell").field("value", &borrow).finish(),
213 Err(_) => {
214 struct BorrowedPlaceholder;
217
218 impl Debug for BorrowedPlaceholder {
219 fn fmt(&self, f: &mut Formatter) {
220 f.write_display("<borrowed>")
221 }
222 }
223
224 f.debug_struct("RefCell")
225 .field("value", &BorrowedPlaceholder)
226 .finish()
227 }
228 }
229 }
230}
231
232impl<T: ?Sized + Debug> Debug for std::cell::Ref<'_, T> {
233 fn fmt(&self, f: &mut Formatter) {
234 Debug::fmt(&**self, f)
235 }
236}
237
238impl<T: ?Sized + Debug> Debug for std::cell::RefMut<'_, T> {
239 fn fmt(&self, f: &mut Formatter) {
240 Debug::fmt(self.deref(), f)
241 }
242}
243
244impl<T: ?Sized> Debug for std::cell::UnsafeCell<T> {
245 fn fmt(&self, f: &mut Formatter) {
246 f.debug_struct("UnsafeCell").finish_non_exhaustive()
247 }
248}
249
250impl Debug for std::fmt::Arguments<'_> {
251 fn fmt(&self, f: &mut Formatter) {
252 f.write_debug(self)
253 }
254}
255
256impl<T: ?Sized + Debug> Debug for Mutex<T> {
257 fn fmt(&self, f: &mut Formatter) {
258 let mut d = f.debug_struct("Mutex");
259 match self.try_lock() {
260 Ok(guard) => {
261 d.field("data", &&*guard);
262 }
263 Err(TryLockError::Poisoned(err)) => {
264 d.field("data", &&**err.get_ref());
265 }
266 Err(TryLockError::WouldBlock) => {
267 struct LockedPlaceholder;
268 impl Debug for LockedPlaceholder {
269 fn fmt(&self, f: &mut Formatter) {
270 f.write_debug(format_args!("<locked>"))
271 }
272 }
273 d.field("data", &LockedPlaceholder);
274 }
275 }
276 d.field("poisoned", &self.is_poisoned());
277 d.finish_non_exhaustive()
278 }
279}
280
281impl Debug for Layout {
282 fn fmt(&self, f: &mut Formatter) {
283 f.debug_struct("Layout")
284 .field("size", &self.size())
285 .field("align", &self.align())
286 .finish()
287 }
288}
289
290impl<B> Debug for std::borrow::Cow<'_, B>
291where
292 B: Debug + ToOwned + ?Sized,
293 <B as ToOwned>::Owned: Debug,
294{
295 fn fmt(&self, f: &mut Formatter) {
296 match *self {
297 Self::Borrowed(ref b) => Debug::fmt(b, f),
298 Self::Owned(ref o) => Debug::fmt(o, f),
299 }
300 }
301}
302
303impl Debug for std::num::ParseIntError {
304 fn fmt(&self, f: &mut Formatter) {
305 f.debug_struct("ParseIntError")
306 .field("kind", &self.kind())
307 .finish()
308 }
309}
310
311impl Debug for IntErrorKind {
312 fn fmt(&self, f: &mut Formatter) {
313 f.debug_tuple(match self {
314 Self::Empty => "Empty",
315 Self::InvalidDigit => "InvalidDigit",
316 Self::PosOverflow => "PosOverflow",
317 Self::NegOverflow => "NegOverflow",
318 Self::Zero => "Zero",
319 _ => "Unknown",
320 })
321 .finish()
322 }
323}
324
325impl Debug for std::time::Duration {
326 fn fmt(&self, f: &mut Formatter) {
327 f.debug_struct("Duration")
328 .field("secs", &self.as_secs())
329 .field("nanos", &self.subsec_nanos())
330 .finish()
331 }
332}
333
334impl Debug for Box<dyn std::error::Error + '_> {
335 fn fmt(&self, f: &mut Formatter) {
336 f.write_debug(&**self)
338 }
339}
340
341impl Debug for Box<dyn std::error::Error + Send + Sync + '_> {
342 fn fmt(&self, f: &mut Formatter) {
343 f.write_debug(&**self)
345 }
346}
347
348impl Debug for std::io::Error {
349 fn fmt(&self, f: &mut Formatter) {
350 Debug::fmt(&self.kind(), f) }
352}
353impl Debug for std::io::ErrorKind {
354 fn fmt(&self, f: &mut Formatter) {
355 let kind = match self {
357 Self::NotFound => "NotFound",
358 Self::PermissionDenied => "PermissionDenied",
359 Self::ConnectionRefused => "ConnectionRefused",
360 Self::ConnectionReset => "ConnectionReset",
361 Self::ConnectionAborted => "ConnectionAborted",
364 Self::NotConnected => "NotConnected",
365 Self::AddrInUse => "AddrInUse",
366 Self::AddrNotAvailable => "AddrNotAvailable",
367 Self::BrokenPipe => "BrokenPipe",
369 Self::AlreadyExists => "AlreadyExists",
370 Self::WouldBlock => "WouldBlock",
371 Self::InvalidInput => "InvalidInput",
378 Self::InvalidData => "InvalidData",
379 Self::TimedOut => "TimedOut",
380 Self::WriteZero => "WriteZero",
381 Self::Interrupted => "Interrupted",
393 Self::Unsupported => "Unsupported",
394 Self::UnexpectedEof => "UnexpectedEof",
395 Self::OutOfMemory => "OutOfMemory",
396 Self::Other => "Other",
397 _ => "???",
399 };
400 f.write_display(kind)
401 }
402}
403
404impl Debug for std::num::ParseFloatError {
405 fn fmt(&self, f: &mut Formatter) {
406 f.debug_struct("ParseFloatError").finish() }
409}
410
411impl<T: Debug> Debug for std::ops::Range<T> {
412 fn fmt(&self, f: &mut Formatter) {
413 Debug::fmt(&self.start, f);
414 f.word("..");
415 Debug::fmt(&self.end, f);
416 }
417}
418impl<T: Debug> Debug for std::ops::RangeFrom<T> {
419 fn fmt(&self, f: &mut Formatter) {
420 Debug::fmt(&self.start, f);
421 f.word("..");
422 }
423}
424impl Debug for std::ops::RangeFull {
425 fn fmt(&self, f: &mut Formatter) {
426 f.word("..")
427 }
428}
429impl<T: Debug> Debug for std::ops::RangeInclusive<T> {
430 fn fmt(&self, f: &mut Formatter) {
431 Debug::fmt(&self.start(), f);
432 f.word("..=");
433 Debug::fmt(&self.end(), f);
434 }
435}
436impl<T: Debug> Debug for std::ops::RangeTo<T> {
437 fn fmt(&self, f: &mut Formatter) {
438 f.word("..");
439 Debug::fmt(&self.end, f);
440 }
441}
442impl<T: Debug> Debug for std::ops::RangeToInclusive<T> {
443 fn fmt(&self, f: &mut Formatter) {
444 f.word("..=");
445 Debug::fmt(&self.end, f);
446 }
447}
448
449