1use super::{
2 Int, Mode, ParseError,
3 UnitPrefix::{self, *},
4};
5use std::{
6 cmp::{Ord, Ordering},
7 fmt,
8 str::FromStr,
9};
10
11#[derive(Eq, Copy, Clone, Debug, PartialEq, PartialOrd)]
12pub enum SizeVariant {
13 Bit,
14 Byte,
15}
16
17use SizeVariant::*;
18
19#[derive(Eq, Copy, Clone, Debug, PartialEq)]
23pub struct Unit(Option<UnitPrefix>, SizeVariant);
24
25pub mod sizes {
26 use super::*;
27
28 #[rustfmt::skip]
29 pub mod noprefix {
30 use super::*;
31 pub const BIT: Unit = Unit(None, Bit);
32 pub const BYTE: Unit = Unit(None, Byte);
33 }
34
35 #[rustfmt::skip]
36 pub mod decimal {
37 use super::*;
38 pub const KILO_BIT : Unit = Unit::of(Kilo, Bit );
39 pub const MEGA_BIT : Unit = Unit::of(Mega, Bit );
40 pub const GIGA_BIT : Unit = Unit::of(Giga, Bit );
41 pub const TERA_BIT : Unit = Unit::of(Tera, Bit );
42 pub const PETA_BIT : Unit = Unit::of(Peta, Bit );
43 pub const EXA_BIT : Unit = Unit::of(Exa , Bit );
44 pub const KILO_BYTE: Unit = Unit::of(Kilo, Byte);
45 pub const MEGA_BYTE: Unit = Unit::of(Mega, Byte);
46 pub const GIGA_BYTE: Unit = Unit::of(Giga, Byte);
47 pub const TERA_BYTE: Unit = Unit::of(Tera, Byte);
48 pub const PETA_BYTE: Unit = Unit::of(Peta, Byte);
49 pub const EXA_BYTE : Unit = Unit::of(Exa , Byte);
50 #[cfg(feature = "u128")] pub const ZETTA_BIT : Unit = Unit::of(Zetta, Bit );
51 #[cfg(feature = "u128")] pub const YOTTA_BIT : Unit = Unit::of(Yotta, Bit );
52 #[cfg(feature = "u128")] pub const ZETTA_BYTE: Unit = Unit::of(Zetta, Byte);
53 #[cfg(feature = "u128")] pub const YOTTA_BYTE: Unit = Unit::of(Yotta, Byte);
54 }
55
56 #[rustfmt::skip]
57 pub mod binary {
58 use super::*;
59 pub const KIBI_BIT : Unit = Unit::of(Kibi, Bit );
60 pub const MEBI_BIT : Unit = Unit::of(Mebi, Bit );
61 pub const GIBI_BIT : Unit = Unit::of(Gibi, Bit );
62 pub const TEBI_BIT : Unit = Unit::of(Tebi, Bit );
63 pub const PEBI_BIT : Unit = Unit::of(Pebi, Bit );
64 pub const EXBI_BIT : Unit = Unit::of(Exbi, Bit );
65 pub const KIBI_BYTE: Unit = Unit::of(Kibi, Byte);
66 pub const MEBI_BYTE: Unit = Unit::of(Mebi, Byte);
67 pub const GIBI_BYTE: Unit = Unit::of(Gibi, Byte);
68 pub const TEBI_BYTE: Unit = Unit::of(Tebi, Byte);
69 pub const PEBI_BYTE: Unit = Unit::of(Pebi, Byte);
70 pub const EXBI_BYTE: Unit = Unit::of(Exbi, Byte);
71 #[cfg(feature = "u128")] pub const ZEBI_BIT : Unit = Unit::of(Zebi, Bit );
72 #[cfg(feature = "u128")] pub const YOBI_BIT : Unit = Unit::of(Yobi, Bit );
73 #[cfg(feature = "u128")] pub const ZEBI_BYTE: Unit = Unit::of(Zebi, Byte);
74 #[cfg(feature = "u128")] pub const YOBI_BYTE: Unit = Unit::of(Yobi, Byte);
75 }
76
77 pub use {binary::*, decimal::*, noprefix::*};
78
79 #[rustfmt::skip]
80 pub mod bits {
81 pub use super::{
82 BIT,
83 KILO_BIT, KIBI_BIT, MEGA_BIT, MEBI_BIT, GIGA_BIT, GIBI_BIT,
84 TERA_BIT, TEBI_BIT, PETA_BIT, PEBI_BIT, EXA_BIT, EXBI_BIT,
85 };
86
87 #[cfg(feature = "u128")]
88 pub use super::{
89 ZETTA_BIT, ZEBI_BIT, YOTTA_BIT, YOBI_BIT,
90 };
91 }
92
93 #[rustfmt::skip]
94 pub mod bytes {
95 pub use super::{
96 BYTE,
97 KILO_BYTE, KIBI_BYTE, MEGA_BYTE, MEBI_BYTE, GIGA_BYTE, GIBI_BYTE,
98 TERA_BYTE, TEBI_BYTE, PETA_BYTE, PEBI_BYTE, EXA_BYTE, EXBI_BYTE,
99 };
100
101 #[cfg(feature = "u128")]
102 pub use super::{
103 ZETTA_BYTE, ZEBI_BYTE, YOTTA_BYTE, YOBI_BYTE,
104 };
105 }
106
107 #[rustfmt::skip]
108 pub mod prefixed {
109 pub use super::{
110 KILO_BIT, KIBI_BIT, KILO_BYTE, KIBI_BYTE, MEGA_BIT, MEBI_BIT, MEGA_BYTE, MEBI_BYTE,
111 GIGA_BIT, GIBI_BIT, GIGA_BYTE, GIBI_BYTE, TERA_BIT, TEBI_BIT, TERA_BYTE, TEBI_BYTE,
112 PETA_BIT, PEBI_BIT, PETA_BYTE, PEBI_BYTE, EXA_BIT, EXBI_BIT, EXA_BYTE, EXBI_BYTE,
113 };
114
115 #[cfg(feature = "u128")]
116 pub use super::{
117 ZETTA_BIT, ZEBI_BIT, ZETTA_BYTE, ZEBI_BYTE,
118 YOTTA_BIT, YOBI_BIT, YOTTA_BYTE, YOBI_BYTE,
119 };
120 }
121
122 #[rustfmt::skip]
123 pub mod all {
124 pub use super::{
125 BIT, BYTE,
126 KILO_BIT, KIBI_BIT, KILO_BYTE, KIBI_BYTE, MEGA_BIT, MEBI_BIT, MEGA_BYTE, MEBI_BYTE,
127 GIGA_BIT, GIBI_BIT, GIGA_BYTE, GIBI_BYTE, TERA_BIT, TEBI_BIT, TERA_BYTE, TEBI_BYTE,
128 PETA_BIT, PEBI_BIT, PETA_BYTE, PEBI_BYTE, EXA_BIT, EXBI_BIT, EXA_BYTE, EXBI_BYTE,
129 };
130
131 #[cfg(feature = "u128")]
132 pub use super::{
133 ZETTA_BIT, ZEBI_BIT, ZETTA_BYTE, ZEBI_BYTE,
134 YOTTA_BIT, YOBI_BIT, YOTTA_BYTE, YOBI_BYTE,
135 };
136 }
137
138 pub const NOPREFIX: [Unit; 2] = [BIT, BYTE];
139
140 #[rustfmt::skip]
141 pub const DECIMAL: [Unit; {
142 #[cfg(feature = "u128")] { 16 }
143 #[cfg(not(feature = "u128"))] { 12 }
144 }] = [
145 KILO_BIT, KILO_BYTE, MEGA_BIT, MEGA_BYTE, GIGA_BIT, GIGA_BYTE,
146 TERA_BIT, TERA_BYTE, PETA_BIT, PETA_BYTE, EXA_BIT, EXA_BYTE,
147 #[cfg(feature = "u128")] ZETTA_BIT,
148 #[cfg(feature = "u128")] ZETTA_BYTE,
149 #[cfg(feature = "u128")] YOTTA_BIT,
150 #[cfg(feature = "u128")] YOTTA_BYTE,
151 ];
152
153 #[rustfmt::skip]
154 pub const BINARY: [Unit; {
155 #[cfg(feature = "u128")] { 16 }
156 #[cfg(not(feature = "u128"))] { 12 }
157 }] = [
158 KIBI_BIT, KIBI_BYTE, MEBI_BIT, MEBI_BYTE, GIBI_BIT, GIBI_BYTE,
159 TEBI_BIT, TEBI_BYTE, PEBI_BIT, PEBI_BYTE, EXBI_BIT, EXBI_BYTE,
160 #[cfg(feature = "u128")] ZEBI_BIT,
161 #[cfg(feature = "u128")] ZEBI_BYTE,
162 #[cfg(feature = "u128")] YOBI_BIT,
163 #[cfg(feature = "u128")] YOBI_BYTE,
164 ];
165
166 #[rustfmt::skip]
167 pub const BITS: [Unit; {
168 #[cfg(feature = "u128")] { 17 }
169 #[cfg(not(feature = "u128"))] { 13 }
170 }] = [
171 BIT, KILO_BIT, KIBI_BIT, MEGA_BIT, MEBI_BIT, GIGA_BIT, GIBI_BIT,
172 TERA_BIT, TEBI_BIT, PETA_BIT, PEBI_BIT, EXA_BIT, EXBI_BIT,
173 #[cfg(feature = "u128")] ZETTA_BIT,
174 #[cfg(feature = "u128")] ZEBI_BIT,
175 #[cfg(feature = "u128")] YOTTA_BIT,
176 #[cfg(feature = "u128")] YOBI_BIT,
177 ];
178
179 #[rustfmt::skip]
180 pub const BYTES: [Unit; {
181 #[cfg(feature = "u128")] { 17 }
182 #[cfg(not(feature = "u128"))] { 13 }
183 }] = [
184 BYTE, KILO_BYTE, KIBI_BYTE, MEGA_BYTE, MEBI_BYTE, GIGA_BYTE, GIBI_BYTE,
185 TERA_BYTE, TEBI_BYTE, PETA_BYTE, PEBI_BYTE, EXA_BYTE, EXBI_BYTE,
186 #[cfg(feature = "u128")] ZETTA_BYTE,
187 #[cfg(feature = "u128")] ZEBI_BYTE,
188 #[cfg(feature = "u128")] YOTTA_BYTE,
189 #[cfg(feature = "u128")] YOBI_BYTE,
190 ];
191
192 #[rustfmt::skip]
193 pub const PREFIXED: [Unit; {
194 #[cfg(feature = "u128")] { 32 }
195 #[cfg(not(feature = "u128"))] { 24 }
196 }] = [
197 KILO_BIT, KIBI_BIT, KILO_BYTE, KIBI_BYTE, MEGA_BIT, MEBI_BIT, MEGA_BYTE, MEBI_BYTE,
198 GIGA_BIT, GIBI_BIT, GIGA_BYTE, GIBI_BYTE, TERA_BIT, TEBI_BIT, TERA_BYTE, TEBI_BYTE,
199 PETA_BIT, PEBI_BIT, PETA_BYTE, PEBI_BYTE, EXA_BIT, EXBI_BIT, EXA_BYTE, EXBI_BYTE,
200 #[cfg(feature = "u128")] ZETTA_BIT,
201 #[cfg(feature = "u128")] ZEBI_BIT,
202 #[cfg(feature = "u128")] ZETTA_BYTE,
203 #[cfg(feature = "u128")] ZEBI_BYTE,
204 #[cfg(feature = "u128")] YOTTA_BIT,
205 #[cfg(feature = "u128")] YOBI_BIT,
206 #[cfg(feature = "u128")] YOTTA_BYTE,
207 #[cfg(feature = "u128")] YOBI_BYTE,
208 ];
209
210 #[rustfmt::skip]
211 pub const ALL: [Unit; {
212 #[cfg(feature = "u128")] { 34 }
213 #[cfg(not(feature = "u128"))] { 26 }
214 }] = [
215 BIT, BYTE,
216 KILO_BIT, KIBI_BIT, KILO_BYTE, KIBI_BYTE, MEGA_BIT, MEBI_BIT, MEGA_BYTE, MEBI_BYTE,
217 GIGA_BIT, GIBI_BIT, GIGA_BYTE, GIBI_BYTE, TERA_BIT, TEBI_BIT, TERA_BYTE, TEBI_BYTE,
218 PETA_BIT, PEBI_BIT, PETA_BYTE, PEBI_BYTE, EXA_BIT, EXBI_BIT, EXA_BYTE, EXBI_BYTE,
219 #[cfg(feature = "u128")] ZETTA_BIT,
220 #[cfg(feature = "u128")] ZEBI_BIT,
221 #[cfg(feature = "u128")] ZETTA_BYTE,
222 #[cfg(feature = "u128")] ZEBI_BYTE,
223 #[cfg(feature = "u128")] YOTTA_BIT,
224 #[cfg(feature = "u128")] YOBI_BIT,
225 #[cfg(feature = "u128")] YOTTA_BYTE,
226 #[cfg(feature = "u128")] YOBI_BYTE,
227 ];
228}
229
230impl SizeVariant {
231 pub const fn is_bit(&self) -> bool {
232 *self as u8 == 0
233 }
234
235 pub const fn is_byte(&self) -> bool {
236 *self as u8 == 1
237 }
238
239 pub const fn mode(&self) -> Mode {
240 if let Bit = self {
241 return Mode::Bits;
242 }
243 Mode::Default
244 }
245
246 pub const fn symbol(&self) -> &'static str {
247 match self {
248 Bit => "b",
249 Byte => "B",
250 }
251 }
252
253 pub const fn symbol_long(&self, plural: bool, caps: bool) -> &'static str {
254 match self {
255 Bit => match (plural, caps) {
256 (true, true) => "Bits",
257 (false, true) => "Bit",
258 (true, false) => "bits",
259 (false, false) => "bit",
260 },
261 Byte => match (plural, caps) {
262 (true, true) => "Bytes",
263 (false, true) => "Byte",
264 (true, false) => "bytes",
265 (false, false) => "byte",
266 },
267 }
268 }
269
270 pub const fn effective_value(&self) -> u8 {
271 match self {
272 Bit => 1,
273 Byte => 8,
274 }
275 }
276}
277
278impl fmt::Display for SizeVariant {
279 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
280 let variant = if f.alternate() {
281 self.symbol_long(f.sign_plus(), true)
282 } else {
283 self.symbol()
284 };
285 f.write_str(variant)
286 }
287}
288
289impl FromStr for SizeVariant {
290 type Err = ParseError;
291
292 fn from_str(s: &str) -> Result<Self, Self::Err> {
293 match s {
294 "" => Err(ParseError::EmptyInput),
295 "b" => Ok(Bit),
296 "B" => Ok(Byte),
297 s => match s.to_lowercase().as_str() {
298 "bit" | "bits" => Ok(Bit),
299 "byte" | "bytes" => Ok(Byte),
300 _ => Err(ParseError::InvalidSizeVariant),
301 },
302 }
303 }
304}
305
306impl From<(UnitPrefix, SizeVariant)> for Unit {
307 fn from((prefix, variant): (UnitPrefix, SizeVariant)) -> Self {
308 Self::of(prefix, variant)
309 }
310}
311
312impl From<SizeVariant> for Unit {
313 fn from(variant: SizeVariant) -> Self {
314 Self(None, variant)
315 }
316}
317
318impl From<UnitPrefix> for Unit {
319 fn from(prefix: UnitPrefix) -> Self {
320 Self::of(prefix, SizeVariant::Byte)
321 }
322}
323
324impl Unit {
325 pub const MIN: Unit = Unit(None, Bit);
326 pub const MAX: Unit = Unit::of(UnitPrefix::MAX, Byte);
327
328 #[inline(always)]
329 pub const fn prefix(&self) -> Option<UnitPrefix> {
330 self.0
331 }
332
333 #[inline(always)]
334 pub const fn size_variant(&self) -> SizeVariant {
335 self.1
336 }
337
338 #[inline(always)]
339 const fn of(prefix: UnitPrefix, size_variant: SizeVariant) -> Self {
340 Self(Some(prefix), size_variant)
341 }
342
343 pub const fn is_decimal(&self) -> bool {
344 if let Some(prefix) = self.0 {
345 return prefix.is_decimal();
346 }
347 false
348 }
349
350 pub const fn is_binary(&self) -> bool {
351 if let Some(prefix) = self.0 {
352 return prefix.is_binary();
353 }
354 false
355 }
356
357 pub const fn is_prefixed(&self) -> bool {
358 self.0.is_some()
359 }
360
361 pub const fn is_bit(&self) -> bool {
362 self.1.is_bit()
363 }
364
365 pub const fn is_byte(&self) -> bool {
366 self.1.is_byte()
367 }
368
369 pub const fn index(&self) -> usize {
370 if let Some(prefix) = self.0 {
371 return prefix.index() + 1;
372 }
373 0
374 }
375
376 pub const fn decimal(&self) -> Self {
377 Self(
378 match self.0 {
379 Some(prefix) => Some(prefix.decimal()),
380 None => None,
381 },
382 self.1,
383 )
384 }
385
386 pub const fn binary(&self) -> Self {
387 Self(
388 match self.0 {
389 Some(prefix) => Some(prefix.binary()),
390 None => None,
391 },
392 self.1,
393 )
394 }
395
396 pub const fn bit(&self) -> Self {
397 Self(self.0, Bit)
398 }
399
400 pub const fn byte(&self) -> Self {
401 Self(self.0, Byte)
402 }
403
404 pub const fn effective_value(&self) -> Int {
405 (match self.0 {
406 Some(prefix) => prefix.effective_value(),
407 None => 1,
408 } * self.1.effective_value() as Int)
409 }
410
411 pub const fn mode(&self) -> Mode {
412 match (self.is_decimal(), self.is_bit()) {
413 (false, false) => Mode::Default,
414 (true, false) => Mode::Decimal,
415 (false, true) => Mode::Bits,
416 (true, true) => bitflags_const_or!(Mode::{Decimal | Bits}),
417 }
418 }
419
420 pub const fn symbols(&self) -> (&'static str, &'static str) {
421 (
422 match self.0 {
423 Some(prefix) => prefix.symbol(),
424 None => "",
425 },
426 self.1.symbol(),
427 )
428 }
429
430 pub fn symbol(&self) -> String {
431 let (prefix, size_variant) = self.symbols();
432 format!("{}{}", prefix, size_variant)
433 }
434
435 pub const fn symbols_long(
436 &self,
437 plural: bool,
438 multi_caps: bool,
439 ) -> (&'static str, &'static str) {
440 (
441 match self.0 {
442 Some(prefix) => prefix.symbol_long(),
443 None => "",
444 },
445 self.1
446 .symbol_long(plural, !self.is_prefixed() || multi_caps),
447 )
448 }
449
450 pub fn symbol_long(&self, plural: bool, multi_caps: bool) -> String {
451 let (prefix, size_variant) = self.symbols_long(plural, multi_caps);
452 format!("{}{}", prefix, size_variant)
453 }
454
455 pub const fn symbol_condensed(&self) -> &'static str {
457 match self.0 {
458 Some(prefix) => prefix.symbol_initials(),
459 None => self.1.symbol(),
460 }
461 }
462
463 pub const fn symbols_initials(&self) -> (&'static str, &'static str) {
464 (
465 match self.0 {
466 Some(prefix) => prefix.symbol_initials(),
467 None => "",
468 },
469 self.1.symbol(),
470 )
471 }
472
473 pub fn symbol_initials(&self) -> String {
474 let (prefix, size_variant) = self.symbols_initials();
475 format!("{}{}", prefix, size_variant)
476 }
477}
478
479impl Ord for Unit {
480 #[inline]
481 fn cmp(&self, other: &Self) -> Ordering {
482 self.effective_value().cmp(&other.effective_value())
483 }
484}
485
486impl PartialOrd for Unit {
487 #[inline]
488 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
489 Some(self.cmp(other))
490 }
491}
492
493impl fmt::Display for Unit {
494 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
495 let unit = if f.sign_plus() {
496 self.symbol_long(!f.alternate(), true)
497 } else if f.sign_minus() {
498 if f.alternate() {
499 self.symbol_condensed().to_string()
500 } else {
501 self.symbol_initials()
502 }
503 } else {
504 self.symbol()
505 };
506 write!(f, "{}", unit)
507 }
508}
509
510impl FromStr for Unit {
511 type Err = ParseError;
512
513 fn from_str(s: &str) -> Result<Self, Self::Err> {
514 if s.is_empty() {
515 Err(ParseError::EmptyInput)
516 } else {
517 let index = s.rfind(|c| matches!(c, 'b' | 'B')).unwrap_or(0);
518 let (prefix, size_variant) = s.split_at(index);
519 let size_variant = size_variant.parse::<SizeVariant>()?;
520 #[rustfmt::skip]
521 let prefix = (!prefix.is_empty())
522 .then(|| {
523 let prefix = prefix.parse::<UnitPrefix>();
524 #[cfg(feature = "case-insensitive")] { prefix }
525 #[cfg(not(feature = "case-insensitive"))]
526 {
527 prefix.map_err(|err| match err {
528 ParseError::InvalidPrefixCaseFormat => {
529 ParseError::InvalidUnitCaseFormat
530 }
531 err => err,
532 })
533 }
534 })
535 .transpose()?;
536 Ok(Unit(prefix, size_variant))
537 }
538 }
539}
540
541#[cfg(test)]
542mod tests {
543 use super::{sizes::*, *};
544
545 #[test]
546 fn size_variant() {
547 let bit = Bit;
548 assert!(bit.is_bit());
549 assert!(!bit.is_byte());
550
551 let byte = Byte;
552 assert!(byte.is_byte());
553 assert!(!byte.is_bit());
554 }
555
556 #[test]
557 fn size_variant_cmp() {
558 assert!(Bit < Byte && Byte > Bit);
559 }
560
561 #[test]
562 fn format_display_size_variant_symbol() {
563 let map = [(Bit, "b"), (Byte, "B")];
564
565 for (unit, repr) in map.iter() {
566 assert_eq!(
567 *repr,
568 unit.symbol(),
569 "expected [{:?}] to be represented as {}",
570 unit,
571 repr
572 );
573 assert_eq!(
574 *repr,
575 format!("{}", unit),
576 "expected [{:?}] to be represented as {}",
577 unit,
578 repr
579 );
580 }
581 }
582
583 #[test]
584 fn format_display_size_variant_symbol_long() {
585 #[rustfmt::skip]
586 let map = [
587 (Bit, "Bit"), (Bit, "Bits"),
588 (Byte, "Byte"), (Byte, "Bytes")
589 ];
590
591 for (index, (unit, repr)) in map.iter().enumerate() {
592 assert_eq!(
593 *repr,
594 unit.symbol_long(index % 2 != 0, true),
595 "expected [{:?}] to be represented in long form as [{}]",
596 unit,
597 repr
598 );
599 assert_eq!(
600 repr.to_lowercase(),
601 unit.symbol_long(index % 2 != 0, false),
602 "expected [{:?}] to be represented in its long single-caps form as [{}]",
603 unit,
604 repr
605 );
606 let value = if index % 2 == 0 {
607 format!("{:#}", unit)
608 } else {
609 format!("{:+#}", unit)
610 };
611 assert_eq!(
612 *repr, value,
613 "expected [{:?}] to be represented in long form as [{}]",
614 unit, repr
615 );
616 }
617 }
618
619 #[test]
620 fn size_variant_effective_value() {
621 let map = [(Bit, 1), (Byte, 8)];
622
623 for (size_variant, value) in map.iter() {
624 assert_eq!(
625 *value,
626 size_variant.effective_value(),
627 "expected [{:?}] to have the value [{}]",
628 size_variant,
629 value
630 );
631 }
632 }
633
634 #[test]
635 fn size_variant_str_parse() {
636 assert_eq!(Ok(Bit), "b".parse::<SizeVariant>());
637 assert_eq!(Ok(Byte), "B".parse::<SizeVariant>());
638 assert_eq!(Ok(Bit), "bit".parse::<SizeVariant>());
639 assert_eq!(Ok(Bit), "bits".parse::<SizeVariant>());
640 assert_eq!(Ok(Bit), "Bit".parse::<SizeVariant>());
641 assert_eq!(Ok(Bit), "Bits".parse::<SizeVariant>());
642 assert_eq!(Ok(Byte), "byte".parse::<SizeVariant>());
643 assert_eq!(Ok(Byte), "bytes".parse::<SizeVariant>());
644 assert_eq!(Ok(Byte), "Byte".parse::<SizeVariant>());
645 assert_eq!(Ok(Byte), "Bytes".parse::<SizeVariant>());
646 assert_eq!(Err(ParseError::EmptyInput), "".parse::<SizeVariant>());
647 assert_eq!(
648 Err(ParseError::InvalidSizeVariant),
649 " b ".parse::<SizeVariant>()
650 );
651 assert_eq!(
652 Err(ParseError::InvalidSizeVariant),
653 "B ".parse::<SizeVariant>()
654 );
655 assert_eq!(
656 Err(ParseError::InvalidSizeVariant),
657 " Bytes".parse::<SizeVariant>()
658 );
659 }
660
661 #[test]
662 #[rustfmt::skip]
663 fn unit_cmp() {
664 assert!(KILO_BIT < KIBI_BIT && KIBI_BIT > KILO_BIT );
665 assert!(KIBI_BIT < KILO_BYTE && KILO_BYTE > KIBI_BIT );
666 assert!(KILO_BYTE < KIBI_BYTE && KIBI_BYTE > KILO_BYTE);
667 assert!(KIBI_BYTE < MEGA_BIT && MEGA_BIT > KIBI_BYTE);
668 assert!(MEGA_BIT < MEBI_BIT && MEBI_BIT > MEGA_BIT );
669 assert!(MEBI_BIT < MEGA_BYTE && MEGA_BYTE > MEBI_BIT );
670 assert!(MEGA_BYTE < MEBI_BYTE && MEBI_BYTE > MEGA_BYTE);
671 assert!(MEBI_BYTE < GIGA_BIT && GIGA_BIT > MEBI_BYTE);
672 assert!(GIGA_BIT < GIBI_BIT && GIBI_BIT > GIGA_BIT );
673 assert!(GIBI_BIT < GIGA_BYTE && GIGA_BYTE > GIBI_BIT );
674 assert!(GIGA_BYTE < GIBI_BYTE && GIBI_BYTE > GIGA_BYTE);
675 assert!(GIBI_BYTE < TERA_BIT && TERA_BIT > GIBI_BYTE);
676 assert!(TERA_BIT < TEBI_BIT && TEBI_BIT > TERA_BIT );
677 assert!(TEBI_BIT < TERA_BYTE && TERA_BYTE > TEBI_BIT );
678 assert!(TERA_BYTE < TEBI_BYTE && TEBI_BYTE > TERA_BYTE);
679 assert!(TEBI_BYTE < PETA_BIT && PETA_BIT > TEBI_BYTE);
680 assert!(PETA_BIT < PEBI_BIT && PEBI_BIT > PETA_BIT );
681 assert!(PEBI_BIT < PETA_BYTE && PETA_BYTE > PEBI_BIT );
682 assert!(PETA_BYTE < PEBI_BYTE && PEBI_BYTE > PETA_BYTE);
683 assert!(PEBI_BYTE < EXA_BIT && EXA_BIT > PEBI_BYTE);
684 assert!(EXA_BIT < EXBI_BIT && EXBI_BIT > EXA_BIT );
685 assert!(EXBI_BIT < EXA_BYTE && EXA_BYTE > EXBI_BIT );
686 assert!(EXA_BYTE < EXBI_BYTE && EXBI_BYTE > EXA_BYTE );
687
688 #[cfg(feature = "u128")] assert!(EXBI_BYTE < ZETTA_BIT && ZETTA_BIT > EXBI_BYTE );
689 #[cfg(feature = "u128")] assert!(ZETTA_BIT < ZEBI_BIT && ZEBI_BIT > ZETTA_BIT );
690 #[cfg(feature = "u128")] assert!(ZEBI_BIT < ZETTA_BYTE && ZETTA_BYTE > ZEBI_BIT );
691 #[cfg(feature = "u128")] assert!(ZETTA_BYTE < ZEBI_BYTE && ZEBI_BYTE > ZETTA_BYTE);
692 #[cfg(feature = "u128")] assert!(ZEBI_BYTE < YOTTA_BIT && YOTTA_BIT > ZEBI_BYTE );
693 #[cfg(feature = "u128")] assert!(YOTTA_BIT < YOBI_BIT && YOBI_BIT > YOTTA_BIT );
694 #[cfg(feature = "u128")] assert!(YOBI_BIT < YOTTA_BYTE && YOTTA_BYTE > YOBI_BIT );
695 #[cfg(feature = "u128")] assert!(YOTTA_BYTE < YOBI_BYTE && YOBI_BYTE > YOTTA_BYTE);
696 }
697
698 #[test]
699 fn const_sizes_sorted() {
700 fn is_sorted(prefix: &mut [Unit]) -> bool {
701 let a = prefix.windows(2).all(|lr| lr[0] < lr[1]);
702 prefix.reverse();
703 let b = prefix.windows(2).all(|lr| lr[0] > lr[1]);
704 a && b
705 }
706
707 assert!(is_sorted(&mut { sizes::NOPREFIX }));
708 assert!(is_sorted(&mut { sizes::DECIMAL }));
709 assert!(is_sorted(&mut { sizes::BINARY }));
710 assert!(is_sorted(&mut { sizes::BITS }));
711 assert!(is_sorted(&mut { sizes::BYTES }));
712 assert!(is_sorted(&mut { sizes::PREFIXED }));
713 assert!(is_sorted(&mut { sizes::ALL }));
714 }
715
716 #[test]
717 fn unit_components() {
718 let b = BIT;
719 assert_eq!((None, Bit), (b.prefix(), b.size_variant()));
720
721 let kb = KILO_BIT;
722 assert_eq!((Some(Kilo), Bit), (kb.prefix(), kb.size_variant()));
723
724 #[allow(non_snake_case)]
725 let GB = GIGA_BYTE;
726 assert_eq!((Some(Giga), Byte), (GB.prefix(), GB.size_variant()));
727 }
728
729 #[test]
730 #[rustfmt::skip]
731 fn unit_decimal() {
732 assert_eq!(KILO_BIT, Unit::of(Kilo, Bit));
733 assert_eq!(MEGA_BIT, Unit::of(Mega, Bit));
734 assert_eq!(GIGA_BIT, Unit::of(Giga, Bit));
735 assert_eq!(TERA_BIT, Unit::of(Tera, Bit));
736 assert_eq!(PETA_BIT, Unit::of(Peta, Bit));
737 assert_eq!(EXA_BIT , Unit::of(Exa , Bit));
738 #[cfg(feature = "u128")] assert_eq!(ZETTA_BIT, Unit::of(Zetta, Bit));
739 #[cfg(feature = "u128")] assert_eq!(YOTTA_BIT, Unit::of(Yotta, Bit));
740 assert_eq!(KILO_BYTE, Unit::of(Kilo, Byte));
742 assert_eq!(MEGA_BYTE, Unit::of(Mega, Byte));
743 assert_eq!(GIGA_BYTE, Unit::of(Giga, Byte));
744 assert_eq!(TERA_BYTE, Unit::of(Tera, Byte));
745 assert_eq!(PETA_BYTE, Unit::of(Peta, Byte));
746 assert_eq!(EXA_BYTE , Unit::of(Exa , Byte));
747 #[cfg(feature = "u128")] assert_eq!(ZETTA_BYTE, Unit::of(Zetta, Byte));
748 #[cfg(feature = "u128")] assert_eq!(YOTTA_BYTE, Unit::of(Yotta, Byte));
749 }
750
751 #[test]
752 fn unit_binary() {
753 assert_eq!(KIBI_BIT, Unit::of(Kibi, Bit));
754 assert_eq!(MEBI_BIT, Unit::of(Mebi, Bit));
755 assert_eq!(GIBI_BIT, Unit::of(Gibi, Bit));
756 assert_eq!(TEBI_BIT, Unit::of(Tebi, Bit));
757 assert_eq!(PEBI_BIT, Unit::of(Pebi, Bit));
758 assert_eq!(EXBI_BIT, Unit::of(Exbi, Bit));
759 #[cfg(feature = "u128")]
760 assert_eq!(ZEBI_BIT, Unit::of(Zebi, Bit));
761 #[cfg(feature = "u128")]
762 assert_eq!(YOBI_BIT, Unit::of(Yobi, Bit));
763 assert_eq!(KIBI_BYTE, Unit::of(Kibi, Byte));
765 assert_eq!(MEBI_BYTE, Unit::of(Mebi, Byte));
766 assert_eq!(GIBI_BYTE, Unit::of(Gibi, Byte));
767 assert_eq!(TEBI_BYTE, Unit::of(Tebi, Byte));
768 assert_eq!(PEBI_BYTE, Unit::of(Pebi, Byte));
769 assert_eq!(EXBI_BYTE, Unit::of(Exbi, Byte));
770 #[cfg(feature = "u128")]
771 assert_eq!(ZEBI_BYTE, Unit::of(Zebi, Byte));
772 #[cfg(feature = "u128")]
773 assert_eq!(YOBI_BYTE, Unit::of(Yobi, Byte));
774 }
775
776 #[test]
777 #[rustfmt::skip]
778 fn unit_from_prefix_and_variant() {
779 assert_eq!(GIGA_BIT , Unit::from((Giga, Bit)) ); assert_eq!(KILO_BYTE, Unit::from((Kilo, Byte))); assert_eq!(PEBI_BIT , (Pebi, Bit).into() ); assert_eq!(EXBI_BYTE, Unit::of(Exbi, Byte) ); }
784
785 #[test]
786 fn unit_from_prefix_and_default() {
787 assert_eq!(KILO_BYTE, Unit::from(Kilo));
788 assert_eq!(KIBI_BYTE, Unit::from(Kibi));
789 assert_eq!(GIGA_BYTE, Giga.into());
790 assert_eq!(GIBI_BYTE, Gibi.into());
791 }
792
793 #[test]
794 fn index() {
795 #[rustfmt::skip]
796 let map = [
797 (BIT, 0), (BYTE, 0),
798 (KILO_BIT, 1), (KILO_BYTE, 1),
800 (MEGA_BIT, 2), (MEGA_BYTE, 2),
801 (GIGA_BIT, 3), (GIGA_BYTE, 3),
802 (TERA_BIT, 4), (TERA_BYTE, 4),
803 (PETA_BIT, 5), (PETA_BYTE, 5),
804 (EXA_BIT , 6), (EXA_BYTE , 6),
805 #[cfg(feature = "u128")] (ZETTA_BIT , 7),
806 #[cfg(feature = "u128")] (ZETTA_BYTE, 7),
807 #[cfg(feature = "u128")] (YOTTA_BIT , 8),
808 #[cfg(feature = "u128")] (YOTTA_BYTE, 8),
809 (KIBI_BIT, 1), (KIBI_BYTE, 1),
811 (MEBI_BIT, 2), (MEBI_BYTE, 2),
812 (GIBI_BIT, 3), (GIBI_BYTE, 3),
813 (TEBI_BIT, 4), (TEBI_BYTE, 4),
814 (PEBI_BIT, 5), (PEBI_BYTE, 5),
815 (EXBI_BIT, 6), (EXBI_BYTE, 6),
816 #[cfg(feature = "u128")] (ZEBI_BIT , 7),
817 #[cfg(feature = "u128")] (ZEBI_BYTE, 7),
818 #[cfg(feature = "u128")] (YOBI_BIT , 8),
819 #[cfg(feature = "u128")] (YOBI_BYTE, 8),
820 ];
821
822 for (unit, index) in map.iter() {
823 assert_eq!(
824 *index,
825 unit.index(),
826 "expected [{:?}] to have the index {}",
827 unit,
828 index
829 );
830 }
831 }
832
833 #[test]
834 #[rustfmt::skip]
835 fn unit_to_decimal() {
836 assert_eq!(KILO_BIT, KIBI_BIT.decimal());
837 assert_eq!(MEGA_BIT, MEBI_BIT.decimal());
838 assert_eq!(GIGA_BIT, GIBI_BIT.decimal());
839 assert_eq!(TERA_BIT, TEBI_BIT.decimal());
840 assert_eq!(PETA_BIT, PEBI_BIT.decimal());
841 assert_eq!(EXA_BIT , EXBI_BIT.decimal());
842 #[cfg(feature = "u128")] assert_eq!(ZETTA_BIT, ZEBI_BIT.decimal());
843 #[cfg(feature = "u128")] assert_eq!(YOTTA_BIT, YOBI_BIT.decimal());
844 assert_eq!(KILO_BYTE, KIBI_BYTE.decimal());
846 assert_eq!(MEGA_BYTE, MEBI_BYTE.decimal());
847 assert_eq!(GIGA_BYTE, GIBI_BYTE.decimal());
848 assert_eq!(TERA_BYTE, TEBI_BYTE.decimal());
849 assert_eq!(PETA_BYTE, PEBI_BYTE.decimal());
850 assert_eq!(EXA_BYTE , EXBI_BYTE.decimal());
851 #[cfg(feature = "u128")] assert_eq!(ZETTA_BYTE, ZEBI_BYTE.decimal());
852 #[cfg(feature = "u128")] assert_eq!(YOTTA_BYTE, YOBI_BYTE.decimal());
853 }
854
855 #[test]
856 #[rustfmt::skip]
857 fn unit_to_binary() {
858 assert_eq!(KIBI_BIT, KILO_BIT.binary());
859 assert_eq!(MEBI_BIT, MEGA_BIT.binary());
860 assert_eq!(GIBI_BIT, GIGA_BIT.binary());
861 assert_eq!(TEBI_BIT, TERA_BIT.binary());
862 assert_eq!(PEBI_BIT, PETA_BIT.binary());
863 assert_eq!(EXBI_BIT, EXA_BIT .binary());
864 #[cfg(feature = "u128")] assert_eq!(ZEBI_BIT, ZETTA_BIT.binary());
865 #[cfg(feature = "u128")] assert_eq!(YOBI_BIT, YOTTA_BIT.binary());
866 assert_eq!(KIBI_BYTE, KILO_BYTE.binary());
868 assert_eq!(MEBI_BYTE, MEGA_BYTE.binary());
869 assert_eq!(GIBI_BYTE, GIGA_BYTE.binary());
870 assert_eq!(TEBI_BYTE, TERA_BYTE.binary());
871 assert_eq!(PEBI_BYTE, PETA_BYTE.binary());
872 assert_eq!(EXBI_BYTE, EXA_BYTE .binary());
873 #[cfg(feature = "u128")] assert_eq!(ZEBI_BYTE, ZETTA_BYTE.binary());
874 #[cfg(feature = "u128")] assert_eq!(YOBI_BYTE, YOTTA_BYTE.binary());
875 }
876
877 #[test]
878 #[rustfmt::skip]
879 fn unit_to_bits() {
880 assert_eq!(KILO_BIT, KILO_BIT.bit());
881 assert_eq!(MEGA_BIT, MEGA_BIT.bit());
882 assert_eq!(GIGA_BIT, GIGA_BIT.bit());
883 assert_eq!(TERA_BIT, TERA_BIT.bit());
884 assert_eq!(PETA_BIT, PETA_BIT.bit());
885 assert_eq!(EXA_BIT , EXA_BIT .bit());
886 #[cfg(feature = "u128")] assert_eq!(ZETTA_BIT, ZETTA_BIT.bit());
887 #[cfg(feature = "u128")] assert_eq!(YOTTA_BIT, YOTTA_BIT.bit());
888 assert_eq!(KILO_BIT, KILO_BYTE.bit());
890 assert_eq!(MEGA_BIT, MEGA_BYTE.bit());
891 assert_eq!(GIGA_BIT, GIGA_BYTE.bit());
892 assert_eq!(TERA_BIT, TERA_BYTE.bit());
893 assert_eq!(PETA_BIT, PETA_BYTE.bit());
894 assert_eq!(EXA_BIT , EXA_BYTE .bit());
895 #[cfg(feature = "u128")] assert_eq!(ZETTA_BIT, ZETTA_BYTE.bit());
896 #[cfg(feature = "u128")] assert_eq!(YOTTA_BIT, YOTTA_BYTE.bit());
897 }
898
899 #[test]
900 fn unit_to_bytes() {
901 assert_eq!(KIBI_BYTE, KIBI_BIT.byte());
902 assert_eq!(MEBI_BYTE, MEBI_BIT.byte());
903 assert_eq!(GIBI_BYTE, GIBI_BIT.byte());
904 assert_eq!(TEBI_BYTE, TEBI_BIT.byte());
905 assert_eq!(PEBI_BYTE, PEBI_BIT.byte());
906 assert_eq!(EXBI_BYTE, EXBI_BIT.byte());
907 #[cfg(feature = "u128")]
908 assert_eq!(ZEBI_BYTE, ZEBI_BIT.byte());
909 #[cfg(feature = "u128")]
910 assert_eq!(YOBI_BYTE, YOBI_BIT.byte());
911 assert_eq!(KIBI_BYTE, KIBI_BYTE.byte());
913 assert_eq!(MEBI_BYTE, MEBI_BYTE.byte());
914 assert_eq!(GIBI_BYTE, GIBI_BYTE.byte());
915 assert_eq!(TEBI_BYTE, TEBI_BYTE.byte());
916 assert_eq!(PEBI_BYTE, PEBI_BYTE.byte());
917 assert_eq!(EXBI_BYTE, EXBI_BYTE.byte());
918 #[cfg(feature = "u128")]
919 assert_eq!(ZEBI_BYTE, ZEBI_BYTE.byte());
920 #[cfg(feature = "u128")]
921 assert_eq!(YOBI_BYTE, YOBI_BYTE.byte());
922 }
923
924 #[test]
925 fn unit_is_decimal() {
926 assert!(!BIT.is_decimal());
927 assert!(!BYTE.is_decimal());
928 for unit in sizes::DECIMAL.iter() {
929 assert!(unit.is_decimal())
930 }
931 for unit in sizes::BINARY.iter() {
932 assert!(!unit.is_decimal())
933 }
934 }
935
936 #[test]
937 fn unit_is_binary() {
938 assert!(!BIT.is_binary());
939 assert!(!BYTE.is_binary());
940 for unit in sizes::BINARY.iter() {
941 assert!(unit.is_binary())
942 }
943 for unit in sizes::DECIMAL.iter() {
944 assert!(!unit.is_binary())
945 }
946 }
947
948 #[test]
949 fn unit_is_bit() {
950 for unit in sizes::BITS.iter() {
951 assert!(unit.is_bit())
952 }
953 for unit in sizes::BYTES.iter() {
954 assert!(!unit.is_bit())
955 }
956 }
957
958 #[test]
959 fn unit_is_byte() {
960 for unit in sizes::BYTES.iter() {
961 assert!(unit.is_byte())
962 }
963 for unit in sizes::BITS.iter() {
964 assert!(!unit.is_byte())
965 }
966 }
967
968 #[test]
969 fn unit_is_prefixed() {
970 for unit in sizes::NOPREFIX.iter() {
971 assert!(!unit.is_prefixed())
972 }
973 for unit in sizes::PREFIXED.iter() {
974 assert!(unit.is_prefixed())
975 }
976 }
977
978 #[test]
979 #[rustfmt::skip]
980 fn unit_from_variant() {
981 assert_eq!(BIT , Unit::from(Bit)); assert_eq!(BYTE, Byte.into() ); }
984
985 #[test]
986 fn unit_effective_value() {
987 #[rustfmt::skip]
988 let map = [
989 (BIT , 1), (BYTE , 8),
990 (KILO_BIT, 1000), (KILO_BYTE, 8000),
991 (MEGA_BIT, 1000000), (MEGA_BYTE, 8000000),
992 (GIGA_BIT, 1000000000), (GIGA_BYTE, 8000000000),
993 (TERA_BIT, 1000000000000), (TERA_BYTE, 8000000000000),
994 (PETA_BIT, 1000000000000000), (PETA_BYTE, 8000000000000000),
995 (EXA_BIT , 1000000000000000000), (EXA_BYTE , 8000000000000000000),
996 #[cfg(feature = "u128")] (ZETTA_BIT , 1000000000000000000000),
997 #[cfg(feature = "u128")] (YOTTA_BIT , 1000000000000000000000000),
998 #[cfg(feature = "u128")] (ZETTA_BYTE, 8000000000000000000000),
999 #[cfg(feature = "u128")] (YOTTA_BYTE, 8000000000000000000000000),
1000 (KIBI_BIT, 1024), (KIBI_BYTE, 8192),
1001 (MEBI_BIT, 1048576), (MEBI_BYTE, 8388608),
1002 (GIBI_BIT, 1073741824), (GIBI_BYTE, 8589934592),
1003 (TEBI_BIT, 1099511627776), (TEBI_BYTE, 8796093022208),
1004 (PEBI_BIT, 1125899906842624), (PEBI_BYTE, 9007199254740992),
1005 (EXBI_BIT, 1152921504606846976), (EXBI_BYTE, 9223372036854775808),
1006 #[cfg(feature = "u128")] (ZEBI_BIT , 1180591620717411303424),
1007 #[cfg(feature = "u128")] (YOBI_BIT , 1208925819614629174706176),
1008 #[cfg(feature = "u128")] (ZEBI_BYTE, 9444732965739290427392),
1009 #[cfg(feature = "u128")] (YOBI_BYTE, 9671406556917033397649408),
1010 ];
1011
1012 for (unit, value) in map.iter() {
1013 assert_eq!(
1014 *value,
1015 unit.effective_value(),
1016 "expected [{:?}] to have the value [{}]",
1017 unit,
1018 value
1019 );
1020 }
1021 }
1022
1023 #[test]
1024 fn unit_min_max() {
1025 assert_eq!(Unit(None, Bit), Unit::MIN);
1026 #[cfg(feature = "u128")]
1027 assert_eq!(Unit(Some(Yobi), Byte), Unit::MAX);
1028 #[cfg(not(feature = "u128"))]
1029 assert_eq!(Unit(Some(Exbi), Byte), Unit::MAX);
1030 }
1031
1032 #[test]
1033 fn unit_format_and_display_symbol() {
1034 #[rustfmt::skip]
1035 let map = [
1036 (BIT , "b", "b" , "b" , "Bit" , "Bit" , "Bits" , "Bits" ),
1046 (BYTE , "B", "B" , "B" , "Byte" , "Byte" , "Bytes" , "Bytes" ),
1047 (KILO_BIT , "K", "Kb", "Kb" , "KiloBit" , "Kilobit" , "KiloBits" , "Kilobits" ),
1048 (KILO_BYTE, "K", "KB", "KB" , "KiloByte" , "Kilobyte" , "KiloBytes", "Kilobytes"),
1049 (MEGA_BIT , "M", "Mb", "Mb" , "MegaBit" , "Megabit" , "MegaBits" , "Megabits" ),
1050 (MEGA_BYTE, "M", "MB", "MB" , "MegaByte" , "Megabyte" , "MegaBytes", "Megabytes"),
1051 (GIGA_BIT , "G", "Gb", "Gb" , "GigaBit" , "Gigabit" , "GigaBits" , "Gigabits" ),
1052 (GIGA_BYTE, "G", "GB", "GB" , "GigaByte" , "Gigabyte" , "GigaBytes", "Gigabytes"),
1053 (TERA_BIT , "T", "Tb", "Tb" , "TeraBit" , "Terabit" , "TeraBits" , "Terabits" ),
1054 (TERA_BYTE, "T", "TB", "TB" , "TeraByte" , "Terabyte" , "TeraBytes", "Terabytes"),
1055 (PETA_BIT , "P", "Pb", "Pb" , "PetaBit" , "Petabit" , "PetaBits" , "Petabits" ),
1056 (PETA_BYTE, "P", "PB", "PB" , "PetaByte" , "Petabyte" , "PetaBytes", "Petabytes"),
1057 (EXA_BIT , "E", "Eb", "Eb" , "ExaBit" , "Exabit" , "ExaBits" , "Exabits" ),
1058 (EXA_BYTE , "E", "EB", "EB" , "ExaByte" , "Exabyte" , "ExaBytes" , "Exabytes" ),
1059 #[cfg(feature = "u128")] (ZETTA_BIT , "Z", "Zb", "Zb" , "ZettaBit" , "Zettabit" , "ZettaBits" , "Zettabits" ),
1060 #[cfg(feature = "u128")] (ZETTA_BYTE, "Z", "ZB", "ZB" , "ZettaByte", "Zettabyte", "ZettaBytes", "Zettabytes"),
1061 #[cfg(feature = "u128")] (YOTTA_BIT , "Y", "Yb", "Yb" , "YottaBit" , "Yottabit" , "YottaBits" , "Yottabits" ),
1062 #[cfg(feature = "u128")] (YOTTA_BYTE, "Y", "YB", "YB" , "YottaByte", "Yottabyte", "YottaBytes", "Yottabytes"),
1063 (KIBI_BIT , "K", "Kb", "Kib", "KibiBit" , "Kibibit" , "KibiBits" , "Kibibits" ),
1064 (KIBI_BYTE, "K", "KB", "KiB", "KibiByte" , "Kibibyte" , "KibiBytes", "Kibibytes"),
1065 (MEBI_BIT , "M", "Mb", "Mib", "MebiBit" , "Mebibit" , "MebiBits" , "Mebibits" ),
1066 (MEBI_BYTE, "M", "MB", "MiB", "MebiByte" , "Mebibyte" , "MebiBytes", "Mebibytes"),
1067 (GIBI_BIT , "G", "Gb", "Gib", "GibiBit" , "Gibibit" , "GibiBits" , "Gibibits" ),
1068 (GIBI_BYTE, "G", "GB", "GiB", "GibiByte" , "Gibibyte" , "GibiBytes", "Gibibytes"),
1069 (TEBI_BIT , "T", "Tb", "Tib", "TebiBit" , "Tebibit" , "TebiBits" , "Tebibits" ),
1070 (TEBI_BYTE, "T", "TB", "TiB", "TebiByte" , "Tebibyte" , "TebiBytes", "Tebibytes"),
1071 (PEBI_BIT , "P", "Pb", "Pib", "PebiBit" , "Pebibit" , "PebiBits" , "Pebibits" ),
1072 (PEBI_BYTE, "P", "PB", "PiB", "PebiByte" , "Pebibyte" , "PebiBytes", "Pebibytes"),
1073 (EXBI_BIT , "E", "Eb", "Eib", "ExbiBit" , "Exbibit" , "ExbiBits" , "Exbibits" ),
1074 (EXBI_BYTE, "E", "EB", "EiB", "ExbiByte" , "Exbibyte" , "ExbiBytes", "Exbibytes"),
1075 #[cfg(feature = "u128")] (ZEBI_BIT , "Z", "Zb", "Zib", "ZebiBit" , "Zebibit" , "ZebiBits" , "Zebibits" ),
1076 #[cfg(feature = "u128")] (ZEBI_BYTE, "Z", "ZB", "ZiB", "ZebiByte" , "Zebibyte" , "ZebiBytes" , "Zebibytes" ),
1077 #[cfg(feature = "u128")] (YOBI_BIT , "Y", "Yb", "Yib", "YobiBit" , "Yobibit" , "YobiBits" , "Yobibits" ),
1078 #[cfg(feature = "u128")] (YOBI_BYTE, "Y", "YB", "YiB", "YobiByte" , "Yobibyte" , "YobiBytes" , "Yobibytes" ),
1079 ];
1080
1081 for (
1082 unit,
1083 condensed,
1084 initials,
1085 normal,
1086 long,
1087 long_single_caps,
1088 long_extra,
1089 long_extra_single_caps,
1090 ) in map.iter()
1091 {
1092 assert_eq!(
1093 (*condensed, *condensed),
1094 (unit.symbol_condensed(), format!("{:-#}", unit).as_str()),
1095 "expected [{:?}] to be condensed as [{}]",
1096 unit,
1097 condensed
1098 );
1099 assert_eq!(
1100 (initials.to_string(), initials.to_string()),
1101 (unit.symbol_initials(), format!("{:-}", unit)),
1102 "expected [{:?}] to have initials [{}]",
1103 unit,
1104 initials
1105 );
1106 assert_eq!(
1107 (normal.to_string(), normal.to_string()),
1108 (unit.symbol(), format!("{}", unit)),
1109 "expected [{:?}] to be represented as [{}]",
1110 unit,
1111 normal
1112 );
1113 assert_eq!(
1114 (long.to_string(), long.to_string()),
1115 (unit.symbol_long(false, true), format!("{:+#}", unit)),
1116 "expected [{:?}] to be represented in long form as [{}]",
1117 unit,
1118 long
1119 );
1120 assert_eq!(
1121 long_single_caps.to_string(),
1122 unit.symbol_long(false, false),
1123 "expected [{:?}] to be represented in long single-caps form as [{}]",
1124 unit,
1125 long
1126 );
1127 assert_eq!(
1128 (long_extra.to_string(), long_extra.to_string()),
1129 (unit.symbol_long(true, true), format!("{:+}", unit)),
1130 "expected [{:?}] to be represented in long, plural form as [{}]",
1131 unit,
1132 long_extra
1133 );
1134 assert_eq!(
1135 long_extra_single_caps.to_string(),
1136 unit.symbol_long(true, false),
1137 "expected [{:?}] to be represented in long, plural, single-caps form as [{}]",
1138 unit,
1139 long_extra
1140 );
1141 }
1142 }
1143
1144 #[test]
1145 fn unit_str_parse() {
1146 assert_eq!(Ok(BIT), "b".parse::<Unit>());
1147 assert_eq!(Ok(BYTE), "B".parse::<Unit>());
1148 assert_eq!(Ok(KILO_BIT), "kb".parse::<Unit>());
1149 assert_eq!(Ok(KILO_BYTE), "kB".parse::<Unit>()); assert_eq!(Ok(KILO_BYTE), "KB".parse::<Unit>());
1151 assert_eq!(Ok(KIBI_BIT), "Kib".parse::<Unit>());
1152 assert_eq!(Ok(KIBI_BYTE), "KiB".parse::<Unit>());
1153 #[rustfmt::skip]
1154 assert_eq!(
1155 {
1156 #[cfg(not(feature = "case-insensitive"))]
1157 { Err(ParseError::InvalidUnitCaseFormat) }
1158 #[cfg(feature = "case-insensitive")]
1159 { Ok(KIBI_BIT) }
1160 },
1161 "kib".parse::<Unit>()
1162 );
1163 #[rustfmt::skip]
1164 assert_eq!(
1165 {
1166 #[cfg(not(feature = "case-insensitive"))]
1167 { Err(ParseError::InvalidUnitCaseFormat) }
1168 #[cfg(feature = "case-insensitive")]
1169 { Ok(MEGA_BIT) }
1170 },
1171 "mb".parse::<Unit>()
1179 );
1180 assert_eq!(Ok(MEGA_BIT), "Mb".parse::<Unit>());
1181 assert_eq!(Ok(MEGA_BYTE), "MB".parse::<Unit>());
1182 assert_eq!(Ok(MEBI_BIT), "Mib".parse::<Unit>());
1183 assert_eq!(Ok(MEBI_BYTE), "MiB".parse::<Unit>());
1184 #[rustfmt::skip]
1185 assert_eq!(
1186 {
1187 #[cfg(not(feature = "case-insensitive"))]
1188 { Err(ParseError::InvalidUnitCaseFormat) }
1189 #[cfg(feature = "case-insensitive")]
1190 { Ok(MEBI_BIT) }
1191 },
1192 "mib".parse::<Unit>()
1193 );
1194 assert_eq!(Ok(MEGA_BIT), "MegaBit".parse::<Unit>());
1195 assert_eq!(Ok(MEGA_BYTE), "MegaByte".parse::<Unit>());
1196 assert_eq!(Ok(GIGA_BIT), "gigabit".parse::<Unit>()); assert_eq!(Ok(GIGA_BYTE), "gigabyte".parse::<Unit>());
1198 assert_eq!(Err(ParseError::EmptyInput), "".parse::<Unit>());
1199 assert_eq!(Err(ParseError::InvalidSizeVariant), "m".parse::<Unit>());
1200 assert_eq!(Err(ParseError::InvalidPrefix), "m b".parse::<Unit>());
1201 }
1202}