1#[cfg(feature = "alloc")]
2extern crate alloc;
3#[cfg(feature = "std")]
4extern crate std;
5
6use core::marker::Copy;
7use core::{cell, fmt, num};
8
9use itoa::{Buffer, Integer};
10
11use crate::details::EscapeWrapper;
12
13impl<T: IntMarker> IntKind for &&EscapeWrapper<T> {}
14
15pub trait IntMarker {
17 #[doc(hidden)]
18 type Escaped: fmt::Display;
19
20 #[doc(hidden)]
21 fn escape(&self) -> Self::Escaped;
22}
23
24impl<T: IntMarker> IntMarker for &T {
25 type Escaped = T::Escaped;
26
27 #[inline]
28 fn escape(&self) -> Self::Escaped {
29 T::escape(*self)
30 }
31}
32
33#[doc(hidden)]
34pub trait IntKind {
35 #[inline]
36 fn wrap<T: IntMarker>(&self, value: &T) -> <T as IntMarker>::Escaped {
37 value.escape()
38 }
39}
40
41pub struct ItoaEscape<T: Integer + Copy>(T);
42
43impl<T: Integer + Copy> fmt::Display for ItoaEscape<T> {
44 #[inline]
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 f.write_str(Buffer::new().format(self.0))
47 }
48}
49
50impl<T: Integer + Copy> fmt::Debug for ItoaEscape<T> {
51 #[inline]
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 fmt::Display::fmt(&self, f)
54 }
55}
56
57impl IntMarker for i128 {
58 type Escaped = ItoaEscape<Self>;
59
60 #[inline]
61 fn escape(&self) -> Self::Escaped {
62 ItoaEscape(*self)
63 }
64}
65
66impl IntMarker for i16 {
67 type Escaped = ItoaEscape<Self>;
68
69 #[inline]
70 fn escape(&self) -> Self::Escaped {
71 ItoaEscape(*self)
72 }
73}
74
75impl IntMarker for i32 {
76 type Escaped = ItoaEscape<Self>;
77
78 #[inline]
79 fn escape(&self) -> Self::Escaped {
80 ItoaEscape(*self)
81 }
82}
83
84impl IntMarker for i64 {
85 type Escaped = ItoaEscape<Self>;
86
87 #[inline]
88 fn escape(&self) -> Self::Escaped {
89 ItoaEscape(*self)
90 }
91}
92
93impl IntMarker for i8 {
94 type Escaped = ItoaEscape<Self>;
95
96 #[inline]
97 fn escape(&self) -> Self::Escaped {
98 ItoaEscape(*self)
99 }
100}
101
102impl IntMarker for isize {
103 type Escaped = ItoaEscape<Self>;
104
105 #[inline]
106 fn escape(&self) -> Self::Escaped {
107 ItoaEscape(*self)
108 }
109}
110
111impl IntMarker for u128 {
112 type Escaped = ItoaEscape<Self>;
113
114 #[inline]
115 fn escape(&self) -> Self::Escaped {
116 ItoaEscape(*self)
117 }
118}
119
120impl IntMarker for u16 {
121 type Escaped = ItoaEscape<Self>;
122
123 #[inline]
124 fn escape(&self) -> Self::Escaped {
125 ItoaEscape(*self)
126 }
127}
128
129impl IntMarker for u32 {
130 type Escaped = ItoaEscape<Self>;
131
132 #[inline]
133 fn escape(&self) -> Self::Escaped {
134 ItoaEscape(*self)
135 }
136}
137
138impl IntMarker for u64 {
139 type Escaped = ItoaEscape<Self>;
140
141 #[inline]
142 fn escape(&self) -> Self::Escaped {
143 ItoaEscape(*self)
144 }
145}
146
147impl IntMarker for u8 {
148 type Escaped = ItoaEscape<Self>;
149
150 #[inline]
151 fn escape(&self) -> Self::Escaped {
152 ItoaEscape(*self)
153 }
154}
155
156impl IntMarker for usize {
157 type Escaped = ItoaEscape<Self>;
158
159 #[inline]
160 fn escape(&self) -> Self::Escaped {
161 ItoaEscape(*self)
162 }
163}
164
165impl IntMarker for num::NonZeroI8 {
166 type Escaped = <i8 as IntMarker>::Escaped;
167
168 #[inline]
169 fn escape(&self) -> Self::Escaped {
170 self.get().escape()
171 }
172}
173
174impl IntMarker for num::NonZeroI16 {
175 type Escaped = <i16 as IntMarker>::Escaped;
176
177 #[inline]
178 fn escape(&self) -> Self::Escaped {
179 self.get().escape()
180 }
181}
182
183impl IntMarker for num::NonZeroI32 {
184 type Escaped = <i32 as IntMarker>::Escaped;
185
186 #[inline]
187 fn escape(&self) -> Self::Escaped {
188 self.get().escape()
189 }
190}
191
192impl IntMarker for num::NonZeroI64 {
193 type Escaped = <i64 as IntMarker>::Escaped;
194
195 #[inline]
196 fn escape(&self) -> Self::Escaped {
197 self.get().escape()
198 }
199}
200
201impl IntMarker for num::NonZeroI128 {
202 type Escaped = <i128 as IntMarker>::Escaped;
203
204 #[inline]
205 fn escape(&self) -> Self::Escaped {
206 self.get().escape()
207 }
208}
209
210impl IntMarker for num::NonZeroIsize {
211 type Escaped = <isize as IntMarker>::Escaped;
212
213 #[inline]
214 fn escape(&self) -> Self::Escaped {
215 self.get().escape()
216 }
217}
218
219impl IntMarker for num::NonZeroU8 {
220 type Escaped = <u8 as IntMarker>::Escaped;
221
222 #[inline]
223 fn escape(&self) -> Self::Escaped {
224 self.get().escape()
225 }
226}
227
228impl IntMarker for num::NonZeroU16 {
229 type Escaped = <u16 as IntMarker>::Escaped;
230
231 #[inline]
232 fn escape(&self) -> Self::Escaped {
233 self.get().escape()
234 }
235}
236
237impl IntMarker for num::NonZeroU32 {
238 type Escaped = <u32 as IntMarker>::Escaped;
239
240 #[inline]
241 fn escape(&self) -> Self::Escaped {
242 self.get().escape()
243 }
244}
245
246impl IntMarker for num::NonZeroU64 {
247 type Escaped = <u64 as IntMarker>::Escaped;
248
249 #[inline]
250 fn escape(&self) -> Self::Escaped {
251 self.get().escape()
252 }
253}
254
255impl IntMarker for num::NonZeroU128 {
256 type Escaped = <u128 as IntMarker>::Escaped;
257
258 #[inline]
259 fn escape(&self) -> Self::Escaped {
260 self.get().escape()
261 }
262}
263
264impl IntMarker for num::NonZeroUsize {
265 type Escaped = <usize as IntMarker>::Escaped;
266
267 #[inline]
268 fn escape(&self) -> Self::Escaped {
269 self.get().escape()
270 }
271}
272
273impl<T: IntMarker> IntMarker for cell::Ref<'_, T> {
274 type Escaped = T::Escaped;
275
276 #[inline]
277 fn escape(&self) -> Self::Escaped {
278 let value: &T = self;
279 value.escape()
280 }
281}
282
283impl<T: IntMarker> IntMarker for cell::RefMut<'_, T> {
284 type Escaped = T::Escaped;
285
286 #[inline]
287 fn escape(&self) -> Self::Escaped {
288 let value: &T = self;
289 value.escape()
290 }
291}
292
293impl<T: IntMarker> IntMarker for num::Wrapping<T> {
294 type Escaped = T::Escaped;
295
296 #[inline]
297 fn escape(&self) -> Self::Escaped {
298 self.0.escape()
299 }
300}
301
302#[cfg(feature = "alloc")]
303#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
304const _: () = {
305 impl<T: IntMarker + alloc::borrow::ToOwned> IntMarker for alloc::borrow::Cow<'_, T> {
306 type Escaped = T::Escaped;
307
308 #[inline]
309 fn escape(&self) -> Self::Escaped {
310 let value: &T = self;
311 value.escape()
312 }
313 }
314
315 impl<T: IntMarker> IntMarker for alloc::boxed::Box<T> {
316 type Escaped = T::Escaped;
317
318 #[inline]
319 fn escape(&self) -> Self::Escaped {
320 let value: &T = self;
321 value.escape()
322 }
323 }
324
325 impl<T: IntMarker> IntMarker for alloc::rc::Rc<T> {
326 type Escaped = T::Escaped;
327
328 #[inline]
329 fn escape(&self) -> Self::Escaped {
330 let value: &T = self;
331 value.escape()
332 }
333 }
334
335 impl<T: IntMarker> IntMarker for alloc::sync::Arc<T> {
336 type Escaped = T::Escaped;
337
338 #[inline]
339 fn escape(&self) -> Self::Escaped {
340 let value: &T = self;
341 value.escape()
342 }
343 }
344};
345
346#[cfg(feature = "std")]
347#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
348const _: () = {
349 use std::sync;
350
351 impl<T: IntMarker> IntMarker for sync::MutexGuard<'_, T> {
352 type Escaped = T::Escaped;
353
354 #[inline]
355 fn escape(&self) -> Self::Escaped {
356 let value: &T = self;
357 value.escape()
358 }
359 }
360
361 impl<T: IntMarker> IntMarker for sync::RwLockReadGuard<'_, T> {
362 type Escaped = T::Escaped;
363
364 #[inline]
365 fn escape(&self) -> Self::Escaped {
366 let value: &T = self;
367 value.escape()
368 }
369 }
370
371 impl<T: IntMarker> IntMarker for sync::RwLockWriteGuard<'_, T> {
372 type Escaped = T::Escaped;
373
374 #[inline]
375 fn escape(&self) -> Self::Escaped {
376 let value: &T = self;
377 value.escape()
378 }
379 }
380};