byte_unit/unit/
mod.rs

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/// The unit of bits/bytes.
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17pub enum Unit {
18    /// 8 Bit = 1 byte.
19    Bit,
20    /// 1 B = 1 byte.
21    B,
22    /// 1 Kbit = 125 bytes.
23    Kbit,
24    /// 1 Kibit = 2<sup>7</sup> bytes.
25    Kibit,
26    /// 1 KB = 10<sup>3</sup> bytes.
27    KB,
28    /// 1 KiB = 2<sup>10</sup> bytes.
29    KiB,
30    /// 1 Mbit = 125 * 10<sup>3</sup> bytes.
31    Mbit,
32    /// 1 Mibit = 2<sup>17</sup> bytes.
33    Mibit,
34    /// 1 MB = 10<sup>6</sup> bytes.
35    MB,
36    /// 1 MiB = 2<sup>20</sup> bytes.
37    MiB,
38    /// 1 Gbit = 125 * 10<sup>6</sup> bytes.
39    Gbit,
40    /// 1 Gibit = 2<sup>27</sup> bytes.
41    Gibit,
42    /// 1 GB = 10<sup>9</sup> bytes.
43    GB,
44    /// 1 GiB = 2<sup>30</sup> bytes.
45    GiB,
46    /// 1 Tbit = 125 * 10<sup>9</sup> bytes.
47    Tbit,
48    /// 1 Tibit = 2<sup>37</sup> bytes.
49    Tibit,
50    /// 1 TB = 10<sup>12</sup> bytes.
51    TB,
52    /// 1 TiB = 2<sup>40</sup> bytes.
53    TiB,
54    /// 1 Pbit = 125 * 10<sup>12</sup> bytes.
55    Pbit,
56    /// 1 Pibit = 2<sup>47</sup> bytes.
57    Pibit,
58    /// 1 PB = 10<sup>15</sup> bytes.
59    PB,
60    /// 1 PiB = 2<sup>50</sup> bytes.
61    PiB,
62    /// 1 Ebit = 125 * 10<sup>15</sup> bytes.
63    Ebit,
64    /// 1 Eibit = 2<sup>57</sup> bytes.
65    Eibit,
66    /// 1 EB = 10<sup>18</sup> bytes.
67    EB,
68    /// 1 EiB = 2<sup>60</sup> bytes.
69    EiB,
70    #[cfg(feature = "u128")]
71    /// 1 Zbit = 125 * 10<sup>18</sup> bytes.
72    Zbit,
73    #[cfg(feature = "u128")]
74    /// 1 Zibit = 2<sup>67</sup> bytes.
75    Zibit,
76    #[cfg(feature = "u128")]
77    /// 1 ZB = 10<sup>21</sup> bytes.
78    ZB,
79    #[cfg(feature = "u128")]
80    /// 1 ZiB = 2<sup>70</sup> bytes.
81    ZiB,
82    #[cfg(feature = "u128")]
83    /// 1 Ybit = 125 * 10<sup>21</sup> bytes.
84    Ybit,
85    #[cfg(feature = "u128")]
86    /// 1 Yibit = 2<sup>77</sup> bytes.
87    Yibit,
88    #[cfg(feature = "u128")]
89    /// 1 YB = 10<sup>24</sup> bytes.
90    YB,
91    #[cfg(feature = "u128")]
92    /// 1 YiB = 2<sup>80</sup> bytes.
93    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
103/// Methods for converting a `Unit` instance into a primitive integer.
104impl Unit {
105    /// Retrieve the bit represented by this `Unit` instance.
106    ///
107    /// # Examples
108    ///
109    /// ```
110    /// use byte_unit::Unit;
111    ///
112    /// assert_eq!(1, Unit::Bit.as_bits_u128());
113    /// assert_eq!(8, Unit::B.as_bits_u128());
114    /// assert_eq!(8000, Unit::KB.as_bits_u128());
115    /// assert_eq!(1024, Unit::Kibit.as_bits_u128());
116    /// ```
117    #[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
190/// Methods for converting a `Unit` instance into a string.
191impl Unit {
192    /// Retrieve the string represented by this `Unit` instance.
193    ///
194    /// # Examples
195    ///
196    /// ```
197    /// use byte_unit::Unit;
198    ///
199    /// assert_eq!("B", Unit::B.as_str());
200    /// assert_eq!("KB", Unit::KB.as_str());
201    /// assert_eq!("MiB", Unit::MiB.as_str());
202    /// assert_eq!("Gb", Unit::Gbit.as_str());
203    /// assert_eq!("Tib", Unit::Tibit.as_str());
204    /// ```
205    #[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
254/// Methods for categorizing variants.
255impl Unit {
256    /// Check whether the unit is based on bits.
257    ///
258    /// # Examples
259    ///
260    /// ```
261    /// use byte_unit::Unit;
262    ///
263    /// assert_eq!(false, Unit::KB.is_bit());
264    /// assert_eq!(true, Unit::Kbit.is_bit());
265    /// ```
266    #[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    /// Check whether the unit is based on powers of  **2**.
313    ///
314    /// # Examples
315    ///
316    /// ```
317    /// use byte_unit::Unit;
318    ///
319    /// assert_eq!(false, Unit::KB.is_binary_multiples());
320    /// assert_eq!(true, Unit::KiB.is_binary_multiples());
321    /// ```
322    #[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}