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 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}