nate/
fast_integer.rs

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
15/// Types implementing this marker get printed using [`itoa`](::itoa)
16pub 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};