dbg_pls/impls/
std.rs

1mod collections;
2mod fnptr;
3mod tuple;
4
5use std::{
6    ops,
7    ops::ControlFlow,
8    rc::Rc,
9    sync::{Arc, Mutex, MutexGuard, TryLockError},
10    task::Poll,
11};
12
13use crate::{DebugPls, Formatter};
14use syn::RangeLimits;
15use syn::__private::Span;
16
17impl<T: ?Sized + DebugPls> DebugPls for Box<T> {
18    fn fmt(&self, f: Formatter<'_>) {
19        DebugPls::fmt(&**self, f);
20    }
21}
22
23impl<D: DebugPls + ?Sized> DebugPls for *mut D {
24    fn fmt(&self, f: Formatter<'_>) {
25        <*const D>::fmt(&(*self as *const D), f);
26    }
27}
28
29impl<D: DebugPls + ?Sized> DebugPls for *const D {
30    fn fmt(&self, f: Formatter<'_>) {
31        /// Since the formatting will be identical for all pointer types, use a non-monomorphized
32        /// implementation for the actual formatting to reduce the amount of codegen work needed
33        fn inner(ptr: *const (), f: Formatter<'_>) {
34            let output = format!("{:#x?}", ptr as usize);
35            f.write_expr(syn::ExprLit {
36                attrs: vec![],
37                lit: syn::LitFloat::new(&output, Span::call_site()).into(),
38            });
39        }
40
41        inner((*self).cast(), f);
42    }
43}
44
45impl<'a, D: DebugPls + ?Sized> DebugPls for &'a D {
46    fn fmt(&self, f: Formatter<'_>) {
47        D::fmt(self, f);
48    }
49}
50
51impl<'a, D: DebugPls + ?Sized> DebugPls for &'a mut D {
52    fn fmt(&self, f: Formatter<'_>) {
53        D::fmt(self, f);
54    }
55}
56
57impl<T: ?Sized + DebugPls> DebugPls for Rc<T> {
58    fn fmt(&self, f: Formatter<'_>) {
59        DebugPls::fmt(&**self, f);
60    }
61}
62
63impl<T: ?Sized + DebugPls> DebugPls for Arc<T> {
64    fn fmt(&self, f: Formatter<'_>) {
65        DebugPls::fmt(&**self, f);
66    }
67}
68
69impl<T: ?Sized + DebugPls> DebugPls for MutexGuard<'_, T> {
70    fn fmt(&self, f: Formatter<'_>) {
71        DebugPls::fmt(&**self, f);
72    }
73}
74
75impl<T: ?Sized + DebugPls> DebugPls for Mutex<T> {
76    fn fmt(&self, f: Formatter<'_>) {
77        let d = f.debug_struct("Mutex");
78        match self.try_lock() {
79            Ok(guard) => d.field("data", &&*guard),
80            Err(TryLockError::Poisoned(err)) => d.field("data", &&**err.get_ref()),
81            Err(TryLockError::WouldBlock) => d.field("data", &"<locked>"),
82        }
83        .field("poisoned", &self.is_poisoned())
84        .finish_non_exhaustive();
85    }
86}
87
88macro_rules! debug_integers {
89    ($($T:ident)*) => {$(
90        impl DebugPls for $T {
91            fn fmt(&self, f: Formatter<'_>) {
92                let mut buf = itoa::Buffer::new();
93                f.write_expr(syn::ExprLit {
94                    attrs: vec![],
95                    lit: syn::LitInt::new(buf.format(*self), Span::call_site()).into(),
96                });
97            }
98        }
99    )*};
100}
101
102debug_integers! {
103  i8 i16 i32 i64 i128 isize
104  u8 u16 u32 u64 u128 usize
105}
106
107macro_rules! debug_non_zero_integers {
108    ($($T:ident)*) => {$(
109        impl DebugPls for std::num::$T {
110            fn fmt(&self, f: Formatter<'_>) {
111                let mut buf = itoa::Buffer::new();
112                f.write_expr(syn::ExprLit {
113                    attrs: vec![],
114                    lit: syn::LitInt::new(buf.format(self.get()), Span::call_site()).into(),
115                });
116            }
117        }
118    )*};
119}
120
121debug_non_zero_integers! {
122  NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize
123  NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
124}
125
126macro_rules! debug_floats {
127    ($ty:ident) => {
128        impl DebugPls for $ty {
129            fn fmt(&self, f: Formatter<'_>) {
130                let mut buf = ryu::Buffer::new();
131                f.write_expr(syn::ExprLit {
132                    attrs: vec![],
133                    lit: syn::LitFloat::new(buf.format(*self), Span::call_site()).into(),
134                });
135            }
136        }
137    };
138}
139
140debug_floats! { f32 }
141debug_floats! { f64 }
142
143impl DebugPls for bool {
144    fn fmt(&self, f: Formatter<'_>) {
145        f.write_expr(syn::ExprLit {
146            attrs: vec![],
147            lit: syn::Lit::Bool(syn::LitBool {
148                value: *self,
149                span: Span::call_site(),
150            }),
151        });
152    }
153}
154
155impl<D: DebugPls> DebugPls for [D] {
156    fn fmt(&self, f: Formatter<'_>) {
157        f.debug_list().entries(self).finish();
158    }
159}
160
161impl<D: DebugPls, const N: usize> DebugPls for [D; N] {
162    fn fmt(&self, f: Formatter<'_>) {
163        f.debug_list().entries(self).finish();
164    }
165}
166
167impl DebugPls for char {
168    fn fmt(&self, f: Formatter<'_>) {
169        f.write_expr(syn::ExprLit {
170            attrs: vec![],
171            lit: syn::LitChar::new(*self, Span::call_site()).into(),
172        });
173    }
174}
175
176impl DebugPls for str {
177    fn fmt(&self, f: Formatter<'_>) {
178        f.write_expr(syn::ExprLit {
179            attrs: vec![],
180            lit: syn::LitStr::new(self, Span::call_site()).into(),
181        });
182    }
183}
184
185impl DebugPls for String {
186    fn fmt(&self, f: Formatter<'_>) {
187        DebugPls::fmt(self.as_str(), f);
188    }
189}
190
191impl<T: DebugPls, E: DebugPls> DebugPls for Result<T, E> {
192    fn fmt(&self, f: Formatter<'_>) {
193        match self {
194            Ok(t) => f.debug_tuple_struct("Ok").field(t).finish(),
195            Err(e) => f.debug_tuple_struct("Err").field(e).finish(),
196        }
197    }
198}
199
200impl<B: DebugPls, C: DebugPls> DebugPls for ControlFlow<B, C> {
201    fn fmt(&self, f: Formatter<'_>) {
202        match self {
203            ControlFlow::Break(b) => f.debug_tuple_struct("Break").field(b).finish(),
204            ControlFlow::Continue(c) => f.debug_tuple_struct("Continue").field(c).finish(),
205        }
206    }
207}
208
209impl<T: DebugPls> DebugPls for Option<T> {
210    fn fmt(&self, f: Formatter<'_>) {
211        match self {
212            Some(t) => f.debug_tuple_struct("Some").field(t).finish(),
213            None => f.debug_ident("None"),
214        }
215    }
216}
217
218impl<T: DebugPls> DebugPls for Poll<T> {
219    fn fmt(&self, f: Formatter<'_>) {
220        match self {
221            Poll::Ready(t) => f.debug_tuple_struct("Ready").field(t).finish(),
222            Poll::Pending => f.debug_ident("Pending"),
223        }
224    }
225}
226
227impl<T: DebugPls> DebugPls for ops::Range<T> {
228    fn fmt(&self, f: Formatter<'_>) {
229        f.write_expr(syn::ExprRange {
230            attrs: vec![],
231            start: Some(Box::new(Formatter::process(&self.start))),
232            limits: RangeLimits::HalfOpen(syn::token::DotDot::default()),
233            end: Some(Box::new(Formatter::process(&self.end))),
234        });
235    }
236}
237
238impl<T: DebugPls> DebugPls for ops::RangeFrom<T> {
239    fn fmt(&self, f: Formatter<'_>) {
240        f.write_expr(syn::ExprRange {
241            attrs: vec![],
242            start: Some(Box::new(Formatter::process(&self.start))),
243            limits: RangeLimits::HalfOpen(syn::token::DotDot::default()),
244            end: None,
245        });
246    }
247}
248
249impl<T: DebugPls> DebugPls for ops::RangeTo<T> {
250    fn fmt(&self, f: Formatter<'_>) {
251        f.write_expr(syn::ExprRange {
252            attrs: vec![],
253            start: None,
254            limits: RangeLimits::HalfOpen(syn::token::DotDot::default()),
255            end: Some(Box::new(Formatter::process(&self.end))),
256        });
257    }
258}
259
260impl DebugPls for ops::RangeFull {
261    fn fmt(&self, f: Formatter<'_>) {
262        f.write_expr(syn::ExprRange {
263            attrs: vec![],
264            start: None,
265            limits: RangeLimits::HalfOpen(syn::token::DotDot::default()),
266            end: None,
267        });
268    }
269}
270
271impl<T: DebugPls> DebugPls for ops::RangeInclusive<T> {
272    fn fmt(&self, f: Formatter<'_>) {
273        f.write_expr(syn::ExprRange {
274            attrs: vec![],
275            start: Some(Box::new(Formatter::process(&self.start()))),
276            limits: RangeLimits::Closed(syn::token::DotDotEq::default()),
277            end: Some(Box::new(Formatter::process(&self.end()))),
278        });
279    }
280}
281
282impl<T: DebugPls> DebugPls for ops::RangeToInclusive<T> {
283    fn fmt(&self, f: Formatter<'_>) {
284        f.write_expr(syn::ExprRange {
285            attrs: vec![],
286            start: None,
287            limits: RangeLimits::Closed(syn::token::DotDotEq::default()),
288            end: Some(Box::new(Formatter::process(&self.end))),
289        });
290    }
291}