1mod built_in_trait;
2pub(crate) mod parse;
3#[cfg(feature = "rocket")]
4mod rocket_traits;
5#[cfg(feature = "serde")]
6mod serde_traits;
7#[cfg(any(feature = "byte", feature = "bit"))]
8mod unit_type;
9
10use core::fmt::{self, Display, Formatter};
11
12#[cfg(any(feature = "byte", feature = "bit"))]
13pub use unit_type::*;
14
15#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17pub enum Unit {
18    Bit,
20    B,
22    Kbit,
24    Kibit,
26    KB,
28    KiB,
30    Mbit,
32    Mibit,
34    MB,
36    MiB,
38    Gbit,
40    Gibit,
42    GB,
44    GiB,
46    Tbit,
48    Tibit,
50    TB,
52    TiB,
54    Pbit,
56    Pibit,
58    PB,
60    PiB,
62    Ebit,
64    Eibit,
66    EB,
68    EiB,
70    #[cfg(feature = "u128")]
71    Zbit,
73    #[cfg(feature = "u128")]
74    Zibit,
76    #[cfg(feature = "u128")]
77    ZB,
79    #[cfg(feature = "u128")]
80    ZiB,
82    #[cfg(feature = "u128")]
83    Ybit,
85    #[cfg(feature = "u128")]
86    Yibit,
88    #[cfg(feature = "u128")]
89    YB,
91    #[cfg(feature = "u128")]
92    YiB,
94}
95
96impl Display for Unit {
97    #[inline]
98    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
99        Display::fmt(self.as_str(), f)
100    }
101}
102
103impl Unit {
105    #[inline]
118    pub const fn as_bits_u128(self) -> u128 {
119        match self {
120            Unit::Bit => 1,
121            Unit::B => 1 << 3,
122            Unit::Kbit => 1_000,
123            Unit::Kibit => 1 << 10,
124            Unit::KB => Unit::Kbit.as_bits_u128() << 3,
125            Unit::KiB => Unit::Kibit.as_bits_u128() << 3,
126            Unit::Mbit => 1_000_000,
127            Unit::Mibit => 1 << 20,
128            Unit::MB => Unit::Mbit.as_bits_u128() << 3,
129            Unit::MiB => Unit::Mibit.as_bits_u128() << 3,
130            Unit::Gbit => 1_000_000_000,
131            Unit::Gibit => 1 << 30,
132            Unit::GB => Unit::Gbit.as_bits_u128() << 3,
133            Unit::GiB => Unit::Gibit.as_bits_u128() << 3,
134            Unit::Tbit => 1_000_000_000_000,
135            Unit::Tibit => 1 << 40,
136            Unit::TB => Unit::Tbit.as_bits_u128() << 3,
137            Unit::TiB => Unit::Tibit.as_bits_u128() << 3,
138            Unit::Pbit => 1_000_000_000_000_000,
139            Unit::Pibit => 1 << 50,
140            Unit::PB => Unit::Pbit.as_bits_u128() << 3,
141            Unit::PiB => Unit::Pibit.as_bits_u128() << 3,
142            Unit::Ebit => 1_000_000_000_000_000_000,
143            Unit::Eibit => 1 << 60,
144            Unit::EB => Unit::Ebit.as_bits_u128() << 3,
145            Unit::EiB => Unit::Eibit.as_bits_u128() << 3,
146            #[cfg(feature = "u128")]
147            Unit::Zbit => 1_000_000_000_000_000_000_000,
148            #[cfg(feature = "u128")]
149            Unit::Zibit => 1 << 70,
150            #[cfg(feature = "u128")]
151            Unit::ZB => Unit::Zbit.as_bits_u128() << 3,
152            #[cfg(feature = "u128")]
153            Unit::ZiB => Unit::Zibit.as_bits_u128() << 3,
154            #[cfg(feature = "u128")]
155            Unit::Ybit => 1_000_000_000_000_000_000_000_000,
156            #[cfg(feature = "u128")]
157            Unit::Yibit => 1 << 80,
158            #[cfg(feature = "u128")]
159            Unit::YB => Unit::Ybit.as_bits_u128() << 3,
160            #[cfg(feature = "u128")]
161            Unit::YiB => Unit::Yibit.as_bits_u128() << 3,
162        }
163    }
164
165    #[cfg(any(feature = "byte", feature = "bit"))]
166    #[cfg(not(feature = "u128"))]
167    #[inline]
168    pub(crate) const fn as_bits_u64(self) -> u64 {
169        self.as_bits_u128() as u64
170    }
171
172    #[cfg(feature = "byte")]
173    #[inline]
174    pub(crate) const fn as_bytes_u128(self) -> u128 {
175        debug_assert!(!matches!(self, Unit::Bit));
176
177        self.as_bits_u128() >> 3
178    }
179
180    #[cfg(feature = "byte")]
181    #[cfg(not(feature = "u128"))]
182    #[inline]
183    pub(crate) const fn as_bytes_u64(self) -> u64 {
184        debug_assert!(!matches!(self, Unit::Bit));
185
186        self.as_bits_u64() >> 3
187    }
188}
189
190impl Unit {
192    #[inline]
206    pub const fn as_str(self) -> &'static str {
207        match self {
208            Self::Bit => "b",
209            Self::B => "B",
210            Self::Kbit => "Kb",
211            Self::Kibit => "Kib",
212            Self::KB => "KB",
213            Self::KiB => "KiB",
214            Self::Mbit => "Mb",
215            Self::Mibit => "Mib",
216            Self::MB => "MB",
217            Self::MiB => "MiB",
218            Self::Gbit => "Gb",
219            Self::Gibit => "Gib",
220            Self::GB => "GB",
221            Self::GiB => "GiB",
222            Self::Tbit => "Tb",
223            Self::Tibit => "Tib",
224            Self::TB => "TB",
225            Self::TiB => "TiB",
226            Self::Pbit => "Pb",
227            Self::Pibit => "Pib",
228            Self::PB => "PB",
229            Self::PiB => "PiB",
230            Self::Ebit => "Eb",
231            Self::Eibit => "Eib",
232            Self::EB => "EB",
233            Self::EiB => "EiB",
234            #[cfg(feature = "u128")]
235            Self::Zbit => "Zb",
236            #[cfg(feature = "u128")]
237            Self::Zibit => "Zib",
238            #[cfg(feature = "u128")]
239            Self::ZB => "ZB",
240            #[cfg(feature = "u128")]
241            Self::ZiB => "ZiB",
242            #[cfg(feature = "u128")]
243            Self::Ybit => "Yb",
244            #[cfg(feature = "u128")]
245            Self::Yibit => "Yib",
246            #[cfg(feature = "u128")]
247            Self::YB => "YB",
248            #[cfg(feature = "u128")]
249            Self::YiB => "YiB",
250        }
251    }
252}
253
254impl Unit {
256    #[inline]
267    pub const fn is_bit(self) -> bool {
268        #[cfg(feature = "u128")]
269        {
270            matches!(
271                self,
272                Self::Bit
273                    | Self::Kbit
274                    | Self::Kibit
275                    | Self::Mbit
276                    | Self::Mibit
277                    | Self::Gbit
278                    | Self::Gibit
279                    | Self::Tbit
280                    | Self::Tibit
281                    | Self::Pbit
282                    | Self::Pibit
283                    | Self::Ebit
284                    | Self::Eibit
285                    | Self::Zbit
286                    | Self::Zibit
287                    | Self::Ybit
288                    | Self::Yibit
289            )
290        }
291        #[cfg(not(feature = "u128"))]
292        {
293            matches!(
294                self,
295                Self::Bit
296                    | Self::Kbit
297                    | Self::Kibit
298                    | Self::Mbit
299                    | Self::Mibit
300                    | Self::Gbit
301                    | Self::Gibit
302                    | Self::Tbit
303                    | Self::Tibit
304                    | Self::Pbit
305                    | Self::Pibit
306                    | Self::Ebit
307                    | Self::Eibit
308            )
309        }
310    }
311
312    #[inline]
323    pub const fn is_binary_multiples(self) -> bool {
324        #[cfg(feature = "u128")]
325        {
326            matches!(
327                self,
328                Self::B
329                    | Self::Kibit
330                    | Self::KiB
331                    | Self::Mibit
332                    | Self::MiB
333                    | Self::Gibit
334                    | Self::GiB
335                    | Self::Tibit
336                    | Self::TiB
337                    | Self::Pibit
338                    | Self::PiB
339                    | Self::Eibit
340                    | Self::EiB
341                    | Self::Zibit
342                    | Self::ZiB
343                    | Self::Yibit
344                    | Self::YiB
345            )
346        }
347        #[cfg(not(feature = "u128"))]
348        {
349            matches!(
350                self,
351                Self::B
352                    | Self::Kibit
353                    | Self::KiB
354                    | Self::Mibit
355                    | Self::MiB
356                    | Self::Gibit
357                    | Self::GiB
358                    | Self::Tibit
359                    | Self::TiB
360                    | Self::Pibit
361                    | Self::PiB
362                    | Self::Eibit
363                    | Self::EiB
364            )
365        }
366    }
367}
368
369impl Unit {
370    #[cfg(any(feature = "byte", feature = "bit"))]
371    #[allow(dead_code)]
372    #[inline]
373    pub(crate) const fn get_multiples() -> &'static [Self] {
374        &[
375            Self::Kbit,
376            Self::Kibit,
377            Self::KB,
378            Self::KiB,
379            Self::Mbit,
380            Self::Mibit,
381            Self::MB,
382            Self::MiB,
383            Self::Gbit,
384            Self::Gibit,
385            Self::GB,
386            Self::GiB,
387            Self::Tbit,
388            Self::Tibit,
389            Self::TB,
390            Self::TiB,
391            Self::Pbit,
392            Self::Pibit,
393            Self::PB,
394            Self::PiB,
395            Self::Ebit,
396            Self::Eibit,
397            Self::EB,
398            Self::EiB,
399            #[cfg(feature = "u128")]
400            Self::Zbit,
401            #[cfg(feature = "u128")]
402            Self::Zibit,
403            #[cfg(feature = "u128")]
404            Self::ZB,
405            #[cfg(feature = "u128")]
406            Self::ZiB,
407            #[cfg(feature = "u128")]
408            Self::Ybit,
409            #[cfg(feature = "u128")]
410            Self::Yibit,
411            #[cfg(feature = "u128")]
412            Self::YB,
413            #[cfg(feature = "u128")]
414            Self::YiB,
415        ]
416    }
417
418    #[cfg(feature = "byte")]
419    #[inline]
420    pub(crate) const fn get_multiples_bytes() -> &'static [Self] {
421        &[
422            Self::KB,
423            Self::KiB,
424            Self::MB,
425            Self::MiB,
426            Self::GB,
427            Self::GiB,
428            Self::TB,
429            Self::TiB,
430            Self::PB,
431            Self::PiB,
432            Self::EB,
433            Self::EiB,
434            #[cfg(feature = "u128")]
435            Self::ZB,
436            #[cfg(feature = "u128")]
437            Self::ZiB,
438            #[cfg(feature = "u128")]
439            Self::YB,
440            #[cfg(feature = "u128")]
441            Self::YiB,
442        ]
443    }
444
445    #[cfg(feature = "bit")]
446    #[allow(dead_code)]
447    #[inline]
448    pub(crate) const fn get_multiples_bits() -> &'static [Self] {
449        &[
450            Self::Kbit,
451            Self::Kibit,
452            Self::Mbit,
453            Self::Mibit,
454            Self::Gbit,
455            Self::Gibit,
456            Self::Tbit,
457            Self::Tibit,
458            Self::Pbit,
459            Self::Pibit,
460            Self::Ebit,
461            Self::Eibit,
462            #[cfg(feature = "u128")]
463            Self::Zbit,
464            #[cfg(feature = "u128")]
465            Self::Zibit,
466            #[cfg(feature = "u128")]
467            Self::Ybit,
468            #[cfg(feature = "u128")]
469            Self::Yibit,
470        ]
471    }
472}