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}