byte_unit/bit/mod.rs
1mod adjusted;
2mod built_in_traits;
3mod constants;
4mod decimal;
5mod parse;
6#[cfg(feature = "rocket")]
7mod rocket_traits;
8#[cfg(feature = "schemars")]
9mod schemars_traits;
10#[cfg(feature = "serde")]
11mod serde_traits;
12
13use core::fmt::{self, Alignment, Display, Formatter, Write};
14
15pub use adjusted::*;
16use rust_decimal::prelude::*;
17
18use crate::{
19 Unit,
20 common::{ceil_f32, ceil_f64},
21};
22
23#[cfg(feature = "u128")]
24const RONNABIT: u128 = 1_000_000_000_000_000_000_000_000_000; // RB
25
26#[cfg(feature = "u128")]
27#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)]
28/// Representing the size in bits.
29pub struct Bit(u128);
30
31#[cfg(not(feature = "u128"))]
32#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)]
33/// Representing the size in bits.
34pub struct Bit(u64);
35
36impl Display for Bit {
37 /// Formats the value using the given formatter.
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// use byte_unit::{Bit, Unit};
43 ///
44 /// let bit = Bit::from_u64_with_unit(1555, Unit::Kbit).unwrap();
45 ///
46 /// assert_eq!("1555000", bit.to_string());
47 /// ```
48 ///
49 /// ```
50 /// use byte_unit::{Bit, UnitType};
51 ///
52 /// let bit_based_2 = Bit::from_u64(10240);
53 /// let bit_based_10 = Bit::from_u64(10000);
54 ///
55 /// assert_eq!("10240", format!("{bit_based_2}"));
56 /// assert_eq!("10000", format!("{bit_based_10}"));
57 ///
58 /// // with an exact unit
59 /// assert_eq!("10 Kib", format!("{bit_based_2:#}"));
60 /// assert_eq!("10 Kb", format!("{bit_based_10:#}"));
61 ///
62 /// // with an exact unit, no spaces between the value and the unit
63 /// assert_eq!("10Kib", format!("{bit_based_2:-#}"));
64 /// assert_eq!("10Kb", format!("{bit_based_10:-#}"));
65 ///
66 /// // with a width, left alignment
67 /// assert_eq!("10 Kib", format!("{bit_based_2:#10}"));
68 /// assert_eq!("10 Kb", format!("{bit_based_10:#10}"));
69 ///
70 /// // with a width, right alignment
71 /// assert_eq!(" 10 Kib", format!("{bit_based_2:>#10}"));
72 /// assert_eq!(" 10 Kb", format!("{bit_based_10:>#10}"));
73 ///
74 /// // with a width, right alignment, more spaces between the value and the unit
75 /// assert_eq!(" 10 Kib", format!("{bit_based_2:>+#10}"));
76 /// assert_eq!(" 10 Kb", format!("{bit_based_10:>+#10}"));
77 /// ```
78 ///
79 /// ```
80 /// use byte_unit::{Bit, UnitType};
81 ///
82 /// let bit = Bit::from_u64(3211776);
83 ///
84 /// assert_eq!("3211776", format!("{bit}"));
85 ///
86 /// // with a unit, still precisely
87 /// assert_eq!("3136.5 Kib", format!("{bit:#}"));
88 ///
89 /// // with a unit and a larger precision (default is 3), still precisely
90 /// assert_eq!("3.211776 Mb", format!("{bit:#.6}"));
91 ///
92 /// // with a unit and a smaller precision (default is 3), still precisely
93 /// assert_eq!("3211776 b", format!("{bit:#.0}"));
94 /// ```
95 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
96 if f.alternate() {
97 let precision = f.precision().unwrap_or(3);
98
99 let (mut value, unit) = self.get_recoverable_unit(false, precision);
100
101 value = value.normalize();
102
103 let space_length = if f.sign_plus() {
104 4 - unit.as_str().len()
105 } else if f.sign_minus() {
106 0
107 } else {
108 1
109 };
110
111 if let Some(mut width) = f.width() {
112 let l = unit.as_str().len() + space_length;
113
114 if width > l + 1 {
115 width -= l;
116
117 let alignment = f.align().unwrap_or(Alignment::Left);
118
119 match alignment {
120 Alignment::Left | Alignment::Center => {
121 f.write_fmt(format_args!("{value:<width$}"))?
122 },
123 Alignment::Right => f.write_fmt(format_args!("{value:>width$}"))?,
124 }
125 } else {
126 f.write_fmt(format_args!("{value}"))?;
127 }
128 } else {
129 f.write_fmt(format_args!("{value}"))?;
130 }
131
132 for _ in 0..space_length {
133 f.write_char(' ')?;
134 }
135
136 f.write_fmt(format_args!("{unit}"))
137 } else {
138 Display::fmt(&self.0, f)
139 }
140 }
141}
142
143/// Associated functions for building `Bit` instances.
144impl Bit {
145 /// Create a new `Bit` instance from a size in bits.
146 ///
147 /// # Examples
148 ///
149 /// ```
150 /// # use byte_unit::Bit;
151 /// let bit = Bit::from_u128(15000000).unwrap(); // 15 Mb
152 /// ```
153 ///
154 /// # Points to Note
155 ///
156 /// * If the input **size** is too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise), this function will return `None`.
157 #[inline]
158 pub const fn from_u128(size: u128) -> Option<Self> {
159 #[cfg(feature = "u128")]
160 {
161 if size < RONNABIT { Some(Bit(size)) } else { None }
162 }
163
164 #[cfg(not(feature = "u128"))]
165 {
166 if size <= u64::MAX as u128 { Some(Bit(size as u64)) } else { None }
167 }
168 }
169
170 /// Create a new `Bit` instance from a size in bits.
171 ///
172 /// # Examples
173 ///
174 /// ```
175 /// # use byte_unit::Bit;
176 /// let bit = unsafe { Bit::from_u128_unsafe(15000000) }; // 15 Mb
177 /// ```
178 ///
179 /// # Safety
180 /// You must ensure the input **size** is not too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise) on your own.
181 #[inline]
182 pub const unsafe fn from_u128_unsafe(size: u128) -> Self {
183 #[cfg(feature = "u128")]
184 {
185 Bit(size)
186 }
187
188 #[cfg(not(feature = "u128"))]
189 {
190 Bit(size as u64)
191 }
192 }
193
194 /// Create a new `Bit` instance from a size in bits.
195 ///
196 /// # Examples
197 ///
198 /// ```
199 /// # use byte_unit::Bit;
200 /// let bit = Bit::from_u64(15000000); // 15 Mb
201 /// ```
202 #[inline]
203 pub const fn from_u64(size: u64) -> Self {
204 #[cfg(feature = "u128")]
205 {
206 Bit(size as u128)
207 }
208
209 #[cfg(not(feature = "u128"))]
210 {
211 Bit(size)
212 }
213 }
214
215 /// Create a new `Bit` instance from a size in bits.
216 ///
217 /// # Examples
218 ///
219 /// ```
220 /// # use byte_unit::Bit;
221 /// let bit = Bit::from_f64(15000000.0).unwrap(); // 15 Mb
222 /// ```
223 ///
224 /// # Points to Note
225 ///
226 /// * If the input **size** is too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise) or not greater than or equal to **0**, this function will return `None`.
227 /// * The fractional part will be rounded up.
228 #[inline]
229 pub fn from_f64(size: f64) -> Option<Self> {
230 if size >= 0.0 {
231 #[cfg(feature = "u128")]
232 {
233 let size = ceil_f64(size) as u128;
234
235 if size < RONNABIT { Some(Bit(size)) } else { None }
236 }
237
238 #[cfg(not(feature = "u128"))]
239 {
240 let size = ceil_f64(size) as u64;
241
242 if size < u64::MAX { Some(Bit(size)) } else { None }
243 }
244 } else {
245 None
246 }
247 }
248
249 /// Create a new `Bit` instance from a size in bits.
250 ///
251 /// # Examples
252 ///
253 /// ```
254 /// # use byte_unit::Bit;
255 /// let bit = Bit::from_f32(15000000.0).unwrap(); // 15 Mb
256 /// ```
257 ///
258 /// # Points to Note
259 ///
260 /// * If the input **size** is too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise) or not greater than or equal to **0**, this function will return `None`.
261 /// * The fractional part will be rounded up.
262 #[inline]
263 pub fn from_f32(size: f32) -> Option<Self> {
264 if size >= 0.0 {
265 #[cfg(feature = "u128")]
266 {
267 let size = ceil_f32(size) as u128;
268
269 if size < RONNABIT { Some(Bit(size)) } else { None }
270 }
271
272 #[cfg(not(feature = "u128"))]
273 {
274 let size = ceil_f32(size) as u64;
275
276 if size < u64::MAX { Some(Bit(size)) } else { None }
277 }
278 } else {
279 None
280 }
281 }
282
283 /// Create a new `Bit` instance from a size in bits.
284 ///
285 /// # Examples
286 ///
287 /// ```
288 /// # use byte_unit::Bit;
289 /// let bit = Bit::from_i128(15000000).unwrap(); // 15 Mb
290 /// ```
291 ///
292 /// # Points to Note
293 ///
294 /// * If the input **size** is too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise) or negative, this function will return `None`.
295 #[inline]
296 pub const fn from_i128(size: i128) -> Option<Self> {
297 if size >= 0 { Self::from_u128(size as u128) } else { None }
298 }
299
300 /// Create a new `Bit` instance from a size in bits.
301 ///
302 /// # Examples
303 ///
304 /// ```
305 /// # use byte_unit::Bit;
306 /// let bit = Bit::from_i64(15000000).unwrap(); // 15 Mb
307 /// ```
308 ///
309 /// # Points to Note
310 ///
311 /// * If the input **size** is negative, this function will return `None`.
312 #[inline]
313 pub const fn from_i64(size: i64) -> Option<Self> {
314 if size >= 0 { Some(Self::from_u64(size as u64)) } else { None }
315 }
316}
317
318/// Associated functions for building `Bit` instances (with `Unit`).
319impl Bit {
320 /// Create a new `Bit` instance from a size of bits with a unit.
321 ///
322 /// # Examples
323 ///
324 /// ```
325 /// use byte_unit::{Bit, Unit};
326 ///
327 /// let bit = Bit::from_u128_with_unit(15, Unit::Mbit).unwrap(); // 15 Mb
328 /// ```
329 ///
330 /// # Points to Note
331 ///
332 /// * If the calculated bit is too large, this function will return `None`.
333 #[inline]
334 pub const fn from_u128_with_unit(size: u128, unit: Unit) -> Option<Self> {
335 let v = {
336 match unit {
337 Unit::Bit => size,
338 _ => match size.checked_mul(unit.as_bits_u128()) {
339 Some(v) => v,
340 None => return None,
341 },
342 }
343 };
344
345 Self::from_u128(v)
346 }
347
348 /// Create a new `Bit` instance from a size of bits with a unit.
349 ///
350 /// # Examples
351 ///
352 /// ```
353 /// use byte_unit::{Bit, Unit};
354 ///
355 /// let bit = Bit::from_u64_with_unit(15, Unit::Mbit).unwrap(); // 15 Mb
356 /// ```
357 ///
358 /// # Points to Note
359 ///
360 /// * If the calculated bit is too large, this function will return `None`.
361 /// * If the input **unit** is `Bit`, the calculated bit will be rounded up.
362 #[inline]
363 pub const fn from_u64_with_unit(size: u64, unit: Unit) -> Option<Self> {
364 #[cfg(feature = "u128")]
365 {
366 Self::from_u128_with_unit(size as u128, unit)
367 }
368
369 #[cfg(not(feature = "u128"))]
370 {
371 let v = {
372 match unit {
373 Unit::Bit => size,
374 _ => match size.checked_mul(unit.as_bits_u64()) {
375 Some(v) => v,
376 None => return None,
377 },
378 }
379 };
380
381 Some(Self::from_u64(v))
382 }
383 }
384
385 /// Create a new `Bit` instance from a size of bits with a unit.
386 ///
387 /// # Examples
388 ///
389 /// ```
390 /// use byte_unit::{Bit, Unit};
391 ///
392 /// let bit = Bit::from_f64_with_unit(15.0, Unit::Mbit).unwrap(); // 15 Mb
393 /// ```
394 ///
395 /// # Points to Note
396 ///
397 /// * If the calculated bit is too large or not greater than or equal to **0**, this function will return `None`.
398 /// * The calculated bit will be rounded up.
399 #[inline]
400 pub fn from_f64_with_unit(size: f64, unit: Unit) -> Option<Self> {
401 match Decimal::from_f64(size) {
402 Some(size) => Self::from_decimal_with_unit(size, unit),
403 None => None,
404 }
405 }
406
407 /// Create a new `Bit` instance from a size of bits with a unit.
408 ///
409 /// # Examples
410 ///
411 /// ```
412 /// use byte_unit::{Bit, Unit};
413 ///
414 /// let bit = Bit::from_f32_with_unit(15.0, Unit::Mbit).unwrap(); // 15 Mb
415 /// ```
416 ///
417 /// # Points to Note
418 ///
419 /// * If the calculated bit is too large or not greater than or equal to **0**, this function will return `None`.
420 /// * The calculated bit will be rounded up.
421 #[inline]
422 pub fn from_f32_with_unit(size: f32, unit: Unit) -> Option<Self> {
423 match Decimal::from_f32(size) {
424 Some(size) => Self::from_decimal_with_unit(size, unit),
425 None => None,
426 }
427 }
428
429 /// Create a new `Bit` instance from a size of bits with a unit.
430 ///
431 /// # Examples
432 ///
433 /// ```
434 /// use byte_unit::{Bit, Unit};
435 ///
436 /// let bit = Bit::from_i128_with_unit(15, Unit::Mibit).unwrap(); // 15 Mb
437 /// ```
438 ///
439 /// # Points to Note
440 ///
441 /// * If the calculated bit is too large or negative, this function will return `None`.
442 #[inline]
443 pub const fn from_i128_with_unit(size: i128, unit: Unit) -> Option<Self> {
444 if size >= 0 { Self::from_u128_with_unit(size as u128, unit) } else { None }
445 }
446
447 /// Create a new `Bit` instance from a size of bits with a unit.
448 ///
449 /// # Examples
450 ///
451 /// ```
452 /// use byte_unit::{Bit, Unit};
453 ///
454 /// let bit = Bit::from_i64_with_unit(15, Unit::Mbit).unwrap(); // 15 Mb
455 /// ```
456 ///
457 /// # Points to Note
458 ///
459 /// * If the calculated bit is too large or negative, this function will return `None`.
460 #[inline]
461 pub const fn from_i64_with_unit(size: i64, unit: Unit) -> Option<Self> {
462 if size >= 0 { Self::from_u64_with_unit(size as u64, unit) } else { None }
463 }
464}
465
466/// Methods for converting a `Bit` instance into a primitive integer.
467impl Bit {
468 /// Retrieve the bit represented by this `Bit` instance.
469 ///
470 /// # Examples
471 ///
472 /// ```
473 /// use byte_unit::Bit;
474 ///
475 /// let bit = Bit::parse_str("123KiB").unwrap();
476 ///
477 /// let result = bit.as_u128();
478 ///
479 /// assert_eq!(1007616, result);
480 /// ```
481 ///
482 /// ```
483 /// use byte_unit::Bit;
484 ///
485 /// let bit = Bit::parse_str("123Kib").unwrap();
486 ///
487 /// let result = bit.as_u128();
488 ///
489 /// assert_eq!(125952, result);
490 /// ```
491 #[inline]
492 pub const fn as_u128(self) -> u128 {
493 #[cfg(feature = "u128")]
494 {
495 self.0
496 }
497
498 #[cfg(not(feature = "u128"))]
499 {
500 self.0 as u128
501 }
502 }
503
504 /// Retrieve the bit represented by this `Bit` instance. When the `u128` feature is enabled, if the bit is actually greater than **2<sup>64</sup> - 1**, it will return **2<sup>64</sup> - 1**.
505 ///
506 /// # Examples
507 ///
508 /// ```
509 /// use byte_unit::Bit;
510 ///
511 /// let bit = Bit::parse_str("1kb").unwrap();
512 ///
513 /// let result = bit.as_u64();
514 ///
515 /// assert_eq!(1000, result);
516 /// ```
517 ///
518 /// ```
519 /// # #[cfg(feature = "u128")]
520 /// # {
521 /// use byte_unit::Bit;
522 ///
523 /// let bit = Bit::parse_str("1zb").unwrap();
524 ///
525 /// let result = bit.as_u64();
526 ///
527 /// assert_eq!(u64::MAX, result);
528 /// # }
529 /// ```
530 #[inline]
531 pub const fn as_u64(self) -> u64 {
532 #[cfg(feature = "u128")]
533 {
534 if self.0 <= u64::MAX as u128 { self.0 as u64 } else { u64::MAX }
535 }
536
537 #[cfg(not(feature = "u128"))]
538 {
539 self.0
540 }
541 }
542
543 /// Retrieve the bit represented by this `Bit` instance.
544 ///
545 /// # Examples
546 ///
547 /// ```
548 /// use byte_unit::Bit;
549 ///
550 /// let bit = Bit::parse_str("1k").unwrap();
551 ///
552 /// let result = bit.as_u64_checked();
553 ///
554 /// assert_eq!(Some(1000), result);
555 /// ```
556 ///
557 /// ```
558 /// # #[cfg(feature = "u128")]
559 /// # {
560 /// use byte_unit::Bit;
561 ///
562 /// let bit = Bit::parse_str("1zb").unwrap();
563 ///
564 /// let result = bit.as_u64_checked();
565 ///
566 /// assert_eq!(None, result);
567 /// # }
568 /// ```
569 #[inline]
570 pub const fn as_u64_checked(self) -> Option<u64> {
571 #[cfg(feature = "u128")]
572 {
573 if self.0 <= u64::MAX as u128 { Some(self.0 as u64) } else { None }
574 }
575
576 #[cfg(not(feature = "u128"))]
577 {
578 Some(self.0)
579 }
580 }
581}
582
583/// Methods for calculation.
584impl Bit {
585 /// Add another `Bit` instance.
586 ///
587 /// # Examples
588 ///
589 /// ```
590 /// use byte_unit::Bit;
591 ///
592 /// let bit_1 = Bit::from_u64(1024);
593 /// let bit_2 = Bit::from_u64(512);
594 ///
595 /// let bit = bit_1.add(bit_2).unwrap();
596 ///
597 /// assert_eq!(1536, bit.as_u64());
598 /// ```
599 ///
600 /// # Points to Note
601 ///
602 /// * If the calculated bit is too large, this function will return `None`.
603 #[inline]
604 pub const fn add(self, rhs: Bit) -> Option<Bit> {
605 match self.0.checked_add(rhs.0) {
606 Some(v) => Some(Bit(v)),
607 None => None,
608 }
609 }
610
611 /// Subtract another `Bit` instance.
612 ///
613 /// # Examples
614 ///
615 /// ```
616 /// use byte_unit::Bit;
617 ///
618 /// let bit_1 = Bit::from_u64(1024);
619 /// let bit_2 = Bit::from_u64(512);
620 ///
621 /// let bit = bit_1.subtract(bit_2).unwrap();
622 ///
623 /// assert_eq!(512, bit.as_u64());
624 /// ```
625 ///
626 /// # Points to Note
627 ///
628 /// * If the right-hand side is bigger then this `Bit` instance, this function will return `None`.
629 #[inline]
630 pub const fn subtract(self, rhs: Bit) -> Option<Bit> {
631 match self.0.checked_sub(rhs.0) {
632 Some(v) => Some(Bit(v)),
633 None => None,
634 }
635 }
636
637 /// Multiplied by an unsigned integer.
638 ///
639 /// # Examples
640 ///
641 /// ```
642 /// use byte_unit::Bit;
643 ///
644 /// let count = 100;
645 /// let bit = Bit::from_u64(1024);
646 ///
647 /// let total_bit = bit.multiply(100).unwrap();
648 ///
649 /// assert_eq!(102400, total_bit.as_u64());
650 /// ```
651 ///
652 /// # Points to Note
653 ///
654 /// * If the calculated bit is too large, this function will return `None`.
655 #[allow(unexpected_cfgs)]
656 #[inline]
657 pub const fn multiply(self, rhs: usize) -> Option<Bit> {
658 #[cfg(feature = "u128")]
659 {
660 match self.0.checked_mul(rhs as u128) {
661 Some(v) => Some(Bit(v)),
662 None => None,
663 }
664 }
665
666 #[cfg(not(feature = "u128"))]
667 {
668 #[cfg(target_pointer_width = "128")]
669 {
670 if rhs > u64::MAX as usize {
671 return None;
672 }
673 }
674
675 match self.0.checked_mul(rhs as u64) {
676 Some(v) => Some(Bit(v)),
677 None => None,
678 }
679 }
680 }
681
682 /// Divided by an unsigned integer.
683 ///
684 /// # Examples
685 ///
686 /// ```
687 /// use byte_unit::Bit;
688 ///
689 /// let count = 100;
690 /// let bit = Bit::from_u64(1024);
691 ///
692 /// let total_bit = bit.divide(100).unwrap();
693 ///
694 /// assert_eq!(10, total_bit.as_u64());
695 /// ```
696 ///
697 /// # Points to Note
698 ///
699 /// * If the input right-hand side is zero, this function will return `None`.
700 /// * The result will be rounded down.
701 #[allow(unexpected_cfgs)]
702 #[inline]
703 pub const fn divide(self, rhs: usize) -> Option<Bit> {
704 #[cfg(feature = "u128")]
705 {
706 match self.0.checked_div(rhs as u128) {
707 Some(v) => Some(Bit(v)),
708 None => None,
709 }
710 }
711
712 #[cfg(not(feature = "u128"))]
713 {
714 #[cfg(target_pointer_width = "128")]
715 {
716 if rhs > u64::MAX as usize {
717 return None;
718 }
719 }
720
721 match self.0.checked_div(rhs as u64) {
722 Some(v) => Some(Bit(v)),
723 None => None,
724 }
725 }
726 }
727
728 #[inline]
729 pub(crate) const fn mul_8(self) -> Bit {
730 Bit(self.0 * 8)
731 }
732}
733
734/// Methods for finding an unit.
735impl Bit {
736 /// Obtain the largest unit which is the greatest factor of this `Bit` instance.
737 ///
738 /// # Examples
739 ///
740 /// ```
741 /// use byte_unit::{Bit, Unit};
742 ///
743 /// let bit = Bit::from_u64(3145728);
744 ///
745 /// let (n, unit) = bit.get_exact_unit(true);
746 ///
747 /// assert_eq!(3, n);
748 /// assert_eq!(Unit::Mibit, unit);
749 /// ```
750 ///
751 /// ```
752 /// use byte_unit::{Bit, Unit};
753 ///
754 /// let bit = Bit::from_u64(24000000);
755 ///
756 /// let (n, unit) = bit.get_exact_unit(true);
757 ///
758 /// assert_eq!(3, n);
759 /// assert_eq!(Unit::MB, unit);
760 /// ```
761 ///
762 /// ```
763 /// use byte_unit::{Bit, Unit};
764 ///
765 /// let bit = Bit::from_u64(24000000);
766 ///
767 /// let (n, unit) = bit.get_exact_unit(false);
768 ///
769 /// assert_eq!(24, n);
770 /// assert_eq!(Unit::Mbit, unit);
771 /// ```
772 #[inline]
773 pub const fn get_exact_unit(self, allow_in_bytes: bool) -> (u128, Unit) {
774 let bits_v = self.as_u128();
775
776 let a = if allow_in_bytes { Unit::get_multiples() } else { Unit::get_multiples_bits() };
777 let mut i = a.len() - 1;
778
779 loop {
780 let unit = a[i];
781
782 let unit_v = unit.as_bits_u128();
783
784 if bits_v >= unit_v && bits_v % unit_v == 0 {
785 return (bits_v / unit_v, unit);
786 }
787
788 if i == 0 {
789 break;
790 }
791
792 i -= 1;
793 }
794
795 (bits_v, Unit::Bit)
796 }
797}