byte-unit-4.0.13/.cargo_vcs_info.json0000644000000001120000000000100130330ustar { "git": { "sha1": "21ae3cc9c9a14a027c2401fb45d0e86cef1f5f96" } } byte-unit-4.0.13/Cargo.toml0000644000000021140000000000100110350ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "byte-unit" version = "4.0.13" authors = ["Magic Len "] include = ["src/**/*", "Cargo.toml", "README.md", "LICENSE"] description = "A library for interaction with units of bytes." homepage = "https://magiclen.org/byte-unit" readme = "README.md" keywords = ["byte", "unit", "kb", "mb", "gb"] categories = ["no-std", "parser-implementations", "value-formatting"] license = "MIT" repository = "https://github.com/magiclen/byte-unit" [dependencies.serde] version = "1" optional = true [dependencies.utf8-width] version = "0.1" [features] default = ["std", "u128"] std = [] u128 = [] byte-unit-4.0.13/Cargo.toml.orig000064400000000000000000000011510072674642500145460ustar 00000000000000[package] name = "byte-unit" version = "4.0.13" authors = ["Magic Len "] edition = "2018" repository = "https://github.com/magiclen/byte-unit" homepage = "https://magiclen.org/byte-unit" keywords = ["byte", "unit", "kb", "mb", "gb"] categories = ["no-std", "parser-implementations", "value-formatting"] description = "A library for interaction with units of bytes." readme = "README.md" license = "MIT" include = ["src/**/*", "Cargo.toml", "README.md", "LICENSE"] [dependencies] utf8-width = "0.1" serde = { version = "1", optional = true } [features] default = ["std", "u128"] std = [] u128 = []byte-unit-4.0.13/LICENSE000064400000000000000000000020660072674642500126720ustar 00000000000000MIT License Copyright (c) 2018 magiclen.org (Ron Li) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. byte-unit-4.0.13/README.md000064400000000000000000000071320072674642500131430ustar 00000000000000Byte Unit ==================== [![CI](https://github.com/magiclen/Byte-Unit/actions/workflows/ci.yml/badge.svg)](https://github.com/magiclen/Byte-Unit/actions/workflows/ci.yml) A library for interaction with units of bytes. The units are **B** for 1 byte, **KB** for 1000 bytes, **KiB** for 1024 bytes, **MB** for 1000000 bytes, **MiB** for 1048576 bytes, etc, and up to **ZiB** which is 1180591620717411303424 bytes. The data type for storing the size of bytes is `u128` by default, but can also be changed to `u64` by disabling the default features (it will also cause the highest supported unit down to **PiB**). ## Usage ### Macros There are `n_*_bytes` macros can be used. The star `*` means the unit. For example, `n_gb_bytes` can be used to get a **n-GB** value in bytes. ```rust #[macro_use] extern crate byte_unit; let result = n_gb_bytes!(4); assert_eq!(4000000000, result); ``` You may need to assign a primitive type if the `n` is not an integer. ```rust #[macro_use] extern crate byte_unit; let result = n_gb_bytes!(2.5, f64); assert_eq!(2500000000, result); ``` ### Byte The `Byte` structure can be used for representing a size of bytes. The `from_str` associated function can parse any **SIZE** string and return a `Byte` instance in common usage. The format of a **SIZE** string is like "123", "123KiB" or "50.84 MB". ```rust extern crate byte_unit; use byte_unit::Byte; let result = Byte::from_str("50.84 MB").unwrap(); assert_eq!(50840000, result.get_bytes()); ``` You can also use the `from_bytes` and `from_unit` associated functions to create a `Byte` instance. ```rust extern crate byte_unit; use byte_unit::Byte; let result = Byte::from_bytes(1500000); assert_eq!(1500000, result.get_bytes()); ``` ```rust extern crate byte_unit; use byte_unit::{Byte, ByteUnit}; let result = Byte::from_unit(1500f64, ByteUnit::KB).unwrap(); assert_eq!(1500000, result.get_bytes()); ``` ### AdjustedByte To change the unit of a `Byte` instance, you can use the `get_adjusted_unit` method. ```rust extern crate byte_unit; use byte_unit::{Byte, ByteUnit}; let byte = Byte::from_str("123KiB").unwrap(); let adjusted_byte = byte.get_adjusted_unit(ByteUnit::KB); assert_eq!("125.95 KB", adjusted_byte.to_string()); ``` To change the unit of a `Byte` instance automatically and appropriately, you can use the `get_appropriate_unit` method. ```rust extern crate byte_unit; use byte_unit::Byte; let byte = Byte::from_bytes(1500000); let adjusted_byte = byte.get_appropriate_unit(false); assert_eq!("1.50 MB", adjusted_byte.to_string()); ``` ```rust extern crate byte_unit; use byte_unit::Byte; let byte = Byte::from_bytes(1500000); let adjusted_byte = byte.get_appropriate_unit(true); assert_eq!("1.43 MiB", adjusted_byte.to_string()); ``` The number of fractional digits created by the `to_string` method of a `AdjustedByte` instance is `2` unless the `ByteUnit` is `B`. To change the number of fractional digits in the formatted string, you can use the `format` method instead. ```rust extern crate byte_unit; use byte_unit::Byte; let byte = Byte::from_bytes(1500000); let adjusted_byte = byte.get_appropriate_unit(false); assert_eq!("1.5 MB", adjusted_byte.format(1)); ``` ## No Std Disable the default features to compile this crate without std. ```toml [dependencies.byte-unit] version = "*" default-features = false features = ["u128"] ``` ## Serde Support Enable the `serde` feature to support the serde framework. ```toml [dependencies.byte-unit] version = "*" features = ["serde"] ``` ## Crates.io https://crates.io/crates/byte-unit ## Documentation https://docs.rs/byte-unit ## License [MIT](LICENSE)byte-unit-4.0.13/src/adjusted_byte.rs000064400000000000000000000233400072674642500156460ustar 00000000000000use core::cmp::Ordering; use alloc::fmt::{self, Display, Formatter}; use alloc::string::String; use crate::{get_bytes, Byte, ByteUnit}; #[cfg(feature = "serde")] use crate::serde::ser::{Serialize, Serializer}; #[cfg(feature = "serde")] use crate::serde::de::{Deserialize, Deserializer, Error as DeError, Unexpected, Visitor}; #[derive(Debug, Clone, Copy)] /// Generated from the `get_appropriate_unit` and `get_adjusted_unit` methods of a `Byte` object. pub struct AdjustedByte { pub(crate) value: f64, pub(crate) unit: ByteUnit, } impl AdjustedByte { /// Format the `AdjustedByte` object to string. /// /// # Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte = Byte::from_unit(1555f64, ByteUnit::KB).unwrap(); /// /// let result = byte.get_appropriate_unit(false).format(3); /// /// assert_eq!("1.555 MB", result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte = Byte::from_unit(1555.2f64, ByteUnit::B).unwrap(); /// /// let result = byte.get_adjusted_unit(ByteUnit::B).format(3); /// /// assert_eq!("1555 B", result); /// ``` #[inline] pub fn format(&self, fractional_digits: usize) -> String { if self.unit == ByteUnit::B { format!("{:.0} B", self.value) } else { format!("{:.*} {}", fractional_digits, self.value, self.unit) } } #[inline] pub fn get_value(&self) -> f64 { self.value } #[inline] pub fn get_unit(&self) -> ByteUnit { self.unit } /// Create a new `Byte` object from this `AdjustedByte` object. **Accuracy** should be taken care of. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte = Byte::from_str("123456789123456").unwrap(); /// let adjusted_byte = byte.get_adjusted_unit(ByteUnit::GB); /// /// assert_eq!(123456.789123456, adjusted_byte.get_value()); /// /// let byte = adjusted_byte.get_byte(); /// let adjusted_byte = byte.get_adjusted_unit(ByteUnit::GB); /// /// assert_eq!(123456.789123, adjusted_byte.get_value()); /// ``` #[inline] pub fn get_byte(&self) -> Byte { let bytes = get_bytes(self.value, self.unit); Byte::from_bytes(bytes) } } impl Display for AdjustedByte { #[inline] fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { if self.unit == ByteUnit::B { f.write_fmt(format_args!("{:.0} B", self.value)) } else { f.write_fmt(format_args!("{:.2} ", self.value))?; Display::fmt(&self.unit, f) } } } impl PartialEq for AdjustedByte { /// Deal with the logical numeric equivalent. /// /// # Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte1 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap(); /// let byte2 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap(); /// /// assert_eq!(byte1.get_appropriate_unit(false), byte2.get_appropriate_unit(true)); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte1 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap(); /// let byte2 = Byte::from_unit(1f64, ByteUnit::MiB).unwrap(); /// /// assert_eq!(byte1.get_appropriate_unit(true), byte2.get_appropriate_unit(false)); /// ``` #[inline] fn eq(&self, other: &AdjustedByte) -> bool { let s = self.get_byte(); let o = other.get_byte(); s.eq(&o) } } impl Eq for AdjustedByte {} impl PartialOrd for AdjustedByte { #[inline] fn partial_cmp(&self, other: &AdjustedByte) -> Option { let s = self.get_byte(); let o = other.get_byte(); s.partial_cmp(&o) } } impl Ord for AdjustedByte { /// Deal with the logical numeric comparation. /// /// # Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte1 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap(); /// let byte2 = Byte::from_unit(1025f64, ByteUnit::KiB).unwrap(); /// /// assert!(byte1.get_appropriate_unit(false) < byte2.get_appropriate_unit(true)); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte1 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap(); /// let byte2 = Byte::from_unit(1.01f64, ByteUnit::MiB).unwrap(); /// /// assert!(byte1.get_appropriate_unit(true) < byte2.get_appropriate_unit(false)); /// ``` #[inline] fn cmp(&self, other: &AdjustedByte) -> Ordering { let s = self.get_byte(); let o = other.get_byte(); s.cmp(&o) } } impl From for Byte { #[inline] fn from(other: AdjustedByte) -> Byte { other.get_byte() } } #[cfg(feature = "serde")] impl Serialize for AdjustedByte { #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(self.format(2).as_str()) } } #[cfg(feature = "serde")] impl<'de> Deserialize<'de> for AdjustedByte { #[inline] fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct AdjustedByteVisitor; impl<'de> Visitor<'de> for AdjustedByteVisitor { type Value = AdjustedByte; serde_if_integer128! { #[inline] fn visit_i128(self, v: i128) -> Result where E: DeError, { if v < 0 { Err(DeError::invalid_value(Unexpected::Other(format!("integer `{}`", v).as_str()), &self)) } else { #[cfg(feature = "u128")] { Ok(Byte::from_bytes(v as u128).get_appropriate_unit(false)) } #[cfg(not(feature = "u128"))] { if v > u64::max_value() as i128 { Err(DeError::invalid_value(Unexpected::Other(format!("integer `{}`", v).as_str()), &self)) } else { Ok(Byte::from_bytes(v as u64).get_appropriate_unit(false)) } } } } #[inline] fn visit_u128(self, v: u128) -> Result where E: DeError, { #[cfg(feature = "u128")] { Ok(Byte::from_bytes(v).get_appropriate_unit(false)) } #[cfg(not(feature = "u128"))] { if v > u64::max_value() as u128 { Err(DeError::invalid_value(Unexpected::Other(format!("integer `{}`", v).as_str()), &self)) } else { Ok(Byte::from_bytes(v as u64).get_appropriate_unit(false)) } } } } #[inline] fn expecting(&self, f: &mut Formatter) -> Result<(), fmt::Error> { f.write_str("a byte such as 123, \"123\", \"123KiB\" or \"50.84 MB\"") } #[inline] fn visit_str(self, v: &str) -> Result where E: DeError, { Byte::from_str(v).map(|b| b.get_appropriate_unit(false)).map_err(DeError::custom) } #[inline] fn visit_string(self, v: String) -> Result where E: DeError, { Byte::from_str(v.as_str()) .map(|b| b.get_appropriate_unit(false)) .map_err(DeError::custom) } #[inline] fn visit_i64(self, v: i64) -> Result where E: DeError, { if v < 0 { Err(DeError::invalid_value(Unexpected::Signed(v), &self)) } else { #[cfg(feature = "u128")] { Ok(Byte::from_bytes(v as u128).get_appropriate_unit(false)) } #[cfg(not(feature = "u128"))] { Ok(Byte::from_bytes(v as u64).get_appropriate_unit(false)) } } } #[inline] fn visit_u64(self, v: u64) -> Result where E: DeError, { #[cfg(feature = "u128")] { Ok(Byte::from_bytes(v as u128).get_appropriate_unit(false)) } #[cfg(not(feature = "u128"))] { Ok(Byte::from_bytes(v).get_appropriate_unit(false)) } } #[inline] fn visit_f64(self, v: f64) -> Result where E: DeError, { Byte::from_unit(v, ByteUnit::B) .map(|b| b.get_appropriate_unit(false)) .map_err(DeError::custom) } } deserializer.deserialize_any(AdjustedByteVisitor) } } byte-unit-4.0.13/src/byte.rs000064400000000000000000000544250072674642500137730ustar 00000000000000use core::convert::TryFrom; use core::str::FromStr; #[cfg(feature = "serde")] use alloc::string::String; use alloc::fmt::{self, Display, Formatter}; use crate::{ get_char_from_bytes, read_xib, AdjustedByte, ByteError, ByteUnit, ValueIncorrectError, }; #[cfg(feature = "serde")] use crate::serde::ser::{Serialize, Serializer}; #[cfg(feature = "serde")] use crate::serde::de::{Deserialize, Deserializer, Error as DeError, Unexpected, Visitor}; #[cfg(feature = "u128")] #[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)] /// Represent the n-bytes data. Use associated functions: `from_unit`, `from_bytes`, `from_str`, to create the instance. pub struct Byte(u128); #[cfg(not(feature = "u128"))] #[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)] /// Represent the n-bytes data. Use associated functions: `from_unit`, `from_bytes`, `from_str`, to create the instance. pub struct Byte(u64); impl Byte { /// Create a new `Byte` object from a specified value and a unit. **Accuracy** should be taken care of. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_unit(1500f64, ByteUnit::KB).unwrap(); /// /// assert_eq!(1500000, result.get_bytes()); /// ``` #[inline] pub fn from_unit(value: f64, unit: ByteUnit) -> Result { if value < 0f64 { return Err(ValueIncorrectError::Negative(value).into()); } let bytes = get_bytes(value, unit); Ok(Byte(bytes)) } /// Create a new `Byte` object from bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_bytes(1500000); /// /// assert_eq!(1500000, result.get_bytes()); /// ``` #[cfg(feature = "u128")] #[inline] pub const fn from_bytes(bytes: u128) -> Byte { Byte(bytes) } /// Create a new `Byte` object from bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_bytes(1500000); /// /// assert_eq!(1500000, result.get_bytes()); /// ``` #[cfg(not(feature = "u128"))] #[inline] pub const fn from_bytes(bytes: u64) -> Byte { Byte(bytes) } /// Create a new `Byte` object from string. **Accuracy** should be taken care of. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_str("123KiB").unwrap(); /// /// assert_eq!(Byte::from_unit(123f64, ByteUnit::KiB).unwrap(), result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_str("50.84 MB").unwrap(); /// /// assert_eq!(Byte::from_unit(50.84f64, ByteUnit::MB).unwrap(), result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_str("8 B").unwrap(); // 8 bytes /// /// assert_eq!(8, result.get_bytes()); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_str("8").unwrap(); // 8 bytes /// /// assert_eq!(8, result.get_bytes()); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_str("8 b").unwrap(); // 8 bytes /// /// assert_eq!(8, result.get_bytes()); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_str("8 kb").unwrap(); // 8 kilobytes /// /// assert_eq!(8000, result.get_bytes()); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_str("8 kib").unwrap(); // 8 kibibytes /// /// assert_eq!(8192, result.get_bytes()); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let result = Byte::from_str("8 k").unwrap(); // 8 kilobytes /// /// assert_eq!(8000, result.get_bytes()); /// ``` #[inline] #[allow(clippy::should_implement_trait)] pub fn from_str>(s: S) -> Result { let s = s.as_ref().trim(); let mut bytes = s.bytes(); let mut value = match bytes.next() { Some(e) => { match e { b'0'..=b'9' => f64::from(e - b'0'), _ => { return Err( ValueIncorrectError::NotNumber(get_char_from_bytes(e, bytes)).into() ); } } } None => return Err(ValueIncorrectError::NoValue.into()), }; let e = 'outer: loop { match bytes.next() { Some(e) => { match e { b'0'..=b'9' => { value = value * 10.0 + f64::from(e - b'0'); } b'.' => { let mut i = 0.1; loop { match bytes.next() { Some(e) => { match e { b'0'..=b'9' => { value += f64::from(e - b'0') * i; i /= 10.0; } _ => { if (i * 10.0) as u8 == 1 { return Err(ValueIncorrectError::NotNumber( get_char_from_bytes(e, bytes), ) .into()); } match e { b' ' => { loop { match bytes.next() { Some(e) => { match e { b' ' => (), _ => break 'outer Some(e), } } None => break 'outer None, } } } _ => break 'outer Some(e), } } } } None => { if (i * 10.0) as u8 == 1 { return Err(ValueIncorrectError::NotNumber( get_char_from_bytes(e, bytes), ) .into()); } break 'outer None; } } } } b' ' => { loop { match bytes.next() { Some(e) => { match e { b' ' => (), _ => break 'outer Some(e), } } None => break 'outer None, } } } _ => break 'outer Some(e), } } None => break None, } }; let unit = read_xib(e, bytes)?; let bytes = get_bytes(value, unit); Ok(Byte(bytes)) } } impl Byte { /// Get bytes represented by a `Byte` object. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::Byte; /// /// let byte = Byte::from_str("123KiB").unwrap(); /// /// let result = byte.get_bytes(); /// /// assert_eq!(125952, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::Byte; /// /// let byte = Byte::from_str("50.84 MB").unwrap(); /// /// let result = byte.get_bytes(); /// /// assert_eq!(50840000, result); /// ``` #[cfg(feature = "u128")] #[inline] pub const fn get_bytes(&self) -> u128 { self.0 } /// Get bytes represented by a `Byte` object. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::Byte; /// /// let byte = Byte::from_str("123KiB").unwrap(); /// /// let result = byte.get_bytes(); /// /// assert_eq!(125952, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::Byte; /// /// let byte = Byte::from_str("50.84 MB").unwrap(); /// /// let result = byte.get_bytes(); /// /// assert_eq!(50840000, result); /// ``` #[cfg(not(feature = "u128"))] #[inline] pub const fn get_bytes(&self) -> u64 { self.0 } /// Adjust the unit and value for `Byte` object. **Accuracy** should be taken care of. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte = Byte::from_str("123KiB").unwrap(); /// /// let adjusted_byte = byte.get_adjusted_unit(ByteUnit::KB); /// /// assert_eq!("125.95 KB", adjusted_byte.to_string()); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::{Byte, ByteUnit}; /// /// let byte = Byte::from_str("50.84 MB").unwrap(); /// /// let adjusted_byte = byte.get_adjusted_unit(ByteUnit::MiB); /// /// assert_eq!("48.48 MiB", adjusted_byte.to_string()); /// ``` #[inline] pub fn get_adjusted_unit(&self, unit: ByteUnit) -> AdjustedByte { let bytes_f64 = self.0 as f64; let value = bytes_f64 / unit.get_unit_bytes() as f64; AdjustedByte { value, unit, } } /// Find the appropriate unit and value for `Byte` object. **Accuracy** should be taken care of. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::Byte; /// /// let byte = Byte::from_str("123KiB").unwrap(); /// /// let adjusted_byte = byte.get_appropriate_unit(false); /// /// assert_eq!("125.95 KB", adjusted_byte.to_string()); /// ``` /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::Byte; /// /// let byte = Byte::from_str("50.84 MB").unwrap(); /// /// let adjusted_byte = byte.get_appropriate_unit(true); /// /// assert_eq!("48.48 MiB", adjusted_byte.to_string()); /// ``` #[allow(clippy::collapsible_if)] pub fn get_appropriate_unit(&self, binary_multiples: bool) -> AdjustedByte { let bytes = self.0; if binary_multiples { #[cfg(feature = "u128")] { if bytes > n_zib_bytes!() { return self.get_adjusted_unit(ByteUnit::ZiB); } else if bytes > n_eib_bytes!() { return self.get_adjusted_unit(ByteUnit::EiB); } } if bytes > n_pib_bytes!() { self.get_adjusted_unit(ByteUnit::PiB) } else if bytes > n_tib_bytes!() { self.get_adjusted_unit(ByteUnit::TiB) } else if bytes > n_gib_bytes!() { self.get_adjusted_unit(ByteUnit::GiB) } else if bytes > n_mib_bytes!() { self.get_adjusted_unit(ByteUnit::MiB) } else if bytes > n_kib_bytes!() { self.get_adjusted_unit(ByteUnit::KiB) } else { self.get_adjusted_unit(ByteUnit::B) } } else { #[cfg(feature = "u128")] { if bytes > n_zb_bytes!() { return self.get_adjusted_unit(ByteUnit::ZB); } else if bytes > n_eb_bytes!() { return self.get_adjusted_unit(ByteUnit::EB); } } if bytes > n_pb_bytes!() { self.get_adjusted_unit(ByteUnit::PB) } else if bytes > n_tb_bytes!() { self.get_adjusted_unit(ByteUnit::TB) } else if bytes > n_gb_bytes!() { self.get_adjusted_unit(ByteUnit::GB) } else if bytes > n_mb_bytes!() { self.get_adjusted_unit(ByteUnit::MB) } else if bytes > n_kb_bytes!() { self.get_adjusted_unit(ByteUnit::KB) } else { self.get_adjusted_unit(ByteUnit::B) } } } } impl Display for Byte { #[inline] fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { f.write_fmt(format_args!("{}", self.0)) } } #[cfg(feature = "u128")] impl From for u128 { #[inline] fn from(b: Byte) -> u128 { b.0 } } #[cfg(not(feature = "u128"))] impl From for u64 { #[inline] fn from(b: Byte) -> u64 { b.0 } } #[cfg(feature = "u128")] impl From for Byte { #[inline] fn from(u: u128) -> Self { Byte::from_bytes(u) } } #[cfg(feature = "u128")] impl From for Byte { #[inline] fn from(u: usize) -> Self { Byte::from_bytes(u as u128) } } #[cfg(not(feature = "u128"))] impl From for Byte { #[inline] fn from(u: usize) -> Self { Byte::from_bytes(u as u64) } } #[cfg(feature = "u128")] impl From for Byte { #[inline] fn from(u: u64) -> Self { Byte::from_bytes(u as u128) } } #[cfg(not(feature = "u128"))] impl From for Byte { #[inline] fn from(u: u64) -> Self { Byte::from_bytes(u) } } #[cfg(feature = "u128")] impl From for Byte { #[inline] fn from(u: u32) -> Self { Byte::from_bytes(u as u128) } } #[cfg(not(feature = "u128"))] impl From for Byte { #[inline] fn from(u: u32) -> Self { Byte::from_bytes(u as u64) } } #[cfg(feature = "u128")] impl From for Byte { #[inline] fn from(u: u16) -> Self { Byte::from_bytes(u as u128) } } #[cfg(not(feature = "u128"))] impl From for Byte { #[inline] fn from(u: u16) -> Self { Byte::from_bytes(u as u64) } } #[cfg(feature = "u128")] impl From for Byte { #[inline] fn from(u: u8) -> Self { Byte::from_bytes(u as u128) } } #[cfg(not(feature = "u128"))] impl From for Byte { #[inline] fn from(u: u8) -> Self { Byte::from_bytes(u as u64) } } impl TryFrom<&str> for Byte { type Error = ByteError; #[inline] fn try_from(s: &str) -> Result { Byte::from_str(s) } } impl FromStr for Byte { type Err = ByteError; #[inline] fn from_str(s: &str) -> Result { Byte::from_str(s) } } #[cfg(feature = "u128")] #[inline] pub(crate) fn get_bytes(value: f64, unit: ByteUnit) -> u128 { match unit { ByteUnit::B => value as u128, ByteUnit::KB => n_kb_bytes!(value, f64), ByteUnit::KiB => n_kib_bytes!(value, f64), ByteUnit::MB => n_mb_bytes!(value, f64), ByteUnit::MiB => n_mib_bytes!(value, f64), ByteUnit::GB => n_gb_bytes!(value, f64), ByteUnit::GiB => n_gib_bytes!(value, f64), ByteUnit::TB => n_tb_bytes!(value, f64), ByteUnit::TiB => n_tib_bytes!(value, f64), ByteUnit::PB => n_pb_bytes!(value, f64), ByteUnit::PiB => n_pib_bytes!(value, f64), ByteUnit::EB => n_eb_bytes!(value, f64), ByteUnit::EiB => n_eib_bytes!(value, f64), ByteUnit::ZB => n_zb_bytes!(value, f64), ByteUnit::ZiB => n_zib_bytes!(value, f64), } } #[cfg(not(feature = "u128"))] #[inline] pub(crate) fn get_bytes(value: f64, unit: ByteUnit) -> u64 { match unit { ByteUnit::B => value as u64, ByteUnit::KB => n_kb_bytes!(value, f64), ByteUnit::KiB => n_kib_bytes!(value, f64), ByteUnit::MB => n_mb_bytes!(value, f64), ByteUnit::MiB => n_mib_bytes!(value, f64), ByteUnit::GB => n_gb_bytes!(value, f64), ByteUnit::GiB => n_gib_bytes!(value, f64), ByteUnit::TB => n_tb_bytes!(value, f64), ByteUnit::TiB => n_tib_bytes!(value, f64), ByteUnit::PB => n_pb_bytes!(value, f64), ByteUnit::PiB => n_pib_bytes!(value, f64), } } #[cfg(feature = "serde")] impl Serialize for Byte { #[allow(unreachable_code)] #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, { #[cfg(feature = "u128")] { serde_if_integer128! { return serializer.serialize_u128(self.get_bytes()); } unreachable!("the `integer128` feature of the `serde` crate needs to be enabled") } #[cfg(not(feature = "u128"))] { serializer.serialize_u64(self.get_bytes()) } } } #[cfg(feature = "serde")] impl<'de> Deserialize<'de> for Byte { #[inline] fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct ByteVisitor; impl<'de> Visitor<'de> for ByteVisitor { type Value = Byte; serde_if_integer128! { #[inline] fn visit_i128(self, v: i128) -> Result where E: DeError, { if v < 0 { Err(DeError::invalid_value(Unexpected::Other(format!("integer `{}`", v).as_str()), &self)) } else { #[cfg(feature = "u128")] { Ok(Byte::from_bytes(v as u128)) } #[cfg(not(feature = "u128"))] { if v > u64::max_value() as i128 { Err(DeError::invalid_value(Unexpected::Other(format!("integer `{}`", v).as_str()), &self)) } else { Ok(Byte::from_bytes(v as u64)) } } } } #[inline] fn visit_u128(self, v: u128) -> Result where E: DeError, { #[cfg(feature = "u128")] { Ok(Byte::from_bytes(v)) } #[cfg(not(feature = "u128"))] { if v > u64::max_value() as u128 { Err(DeError::invalid_value(Unexpected::Other(format!("integer `{}`", v).as_str()), &self)) } else { Ok(Byte::from_bytes(v as u64)) } } } } #[inline] fn expecting(&self, f: &mut Formatter) -> Result<(), fmt::Error> { f.write_str("a byte such as 123, \"123\", \"123KiB\" or \"50.84 MB\"") } #[inline] fn visit_str(self, v: &str) -> Result where E: DeError, { Byte::from_str(v).map_err(DeError::custom) } #[inline] fn visit_string(self, v: String) -> Result where E: DeError, { Byte::from_str(v.as_str()).map_err(DeError::custom) } #[inline] fn visit_i64(self, v: i64) -> Result where E: DeError, { if v < 0 { Err(DeError::invalid_value(Unexpected::Signed(v), &self)) } else { #[cfg(feature = "u128")] { Ok(Byte::from_bytes(v as u128)) } #[cfg(not(feature = "u128"))] { Ok(Byte::from_bytes(v as u64)) } } } #[inline] fn visit_u64(self, v: u64) -> Result where E: DeError, { #[cfg(feature = "u128")] { Ok(Byte::from_bytes(v as u128)) } #[cfg(not(feature = "u128"))] { Ok(Byte::from_bytes(v)) } } #[inline] fn visit_f64(self, v: f64) -> Result where E: DeError, { Byte::from_unit(v, ByteUnit::B).map_err(DeError::custom) } } deserializer.deserialize_any(ByteVisitor) } } byte-unit-4.0.13/src/byte_error.rs000064400000000000000000000062530072674642500152000ustar 00000000000000#[cfg(feature = "std")] use std::error::Error; use alloc::fmt::{self, Display, Formatter}; #[derive(Debug, Clone)] /// Error types for parsing values. pub enum ValueIncorrectError { Negative(f64), NotNumber(char), NoValue, } impl Display for ValueIncorrectError { #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { match self { ValueIncorrectError::Negative(value) => { f.write_fmt(format_args!("The value `{}` is negative.", value)) } ValueIncorrectError::NotNumber(c) => { f.write_fmt(format_args!("The character {:?} is not a number.", c)) } ValueIncorrectError::NoValue => f.write_str("No value."), } } } #[cfg(feature = "std")] impl Error for ValueIncorrectError {} #[derive(Debug, Clone)] /// Errors for `ByteUnit`. pub struct UnitIncorrectError { pub character: char, pub expected_characters: &'static [char], pub also_expect_no_character: bool, } impl Display for UnitIncorrectError { #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { let expected_characters_length = self.expected_characters.len(); if expected_characters_length == 0 { f.write_fmt(format_args!( "The character {:?} is incorrect. No character is expected.", self.character )) } else { f.write_fmt(format_args!("The character {:?} is incorrect.", self.character))?; f.write_fmt(format_args!(" {:?}", self.expected_characters[0]))?; if expected_characters_length > 1 { for c in self.expected_characters[1..].iter().take(expected_characters_length - 2) { f.write_fmt(format_args!(", {:?}", c))?; } } if self.also_expect_no_character { f.write_fmt(format_args!( ", {:?} or no character is expected.", self.expected_characters[expected_characters_length - 1] )) } else { f.write_fmt(format_args!( " or {:?} is expected.", self.expected_characters[expected_characters_length - 1] )) } } } } #[cfg(feature = "std")] impl Error for UnitIncorrectError {} #[derive(Debug, Clone)] /// Error types for `Byte` and `ByteUnit`. pub enum ByteError { ValueIncorrect(ValueIncorrectError), UnitIncorrect(UnitIncorrectError), } impl From for ByteError { #[inline] fn from(error: ValueIncorrectError) -> Self { ByteError::ValueIncorrect(error) } } impl From for ByteError { #[inline] fn from(error: UnitIncorrectError) -> Self { ByteError::UnitIncorrect(error) } } impl Display for ByteError { #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { match self { ByteError::ValueIncorrect(error) => Display::fmt(error, f), ByteError::UnitIncorrect(error) => Display::fmt(error, f), } } } #[cfg(feature = "std")] impl Error for ByteError {} byte-unit-4.0.13/src/byte_unit.rs000064400000000000000000000324050072674642500150240ustar 00000000000000extern crate utf8_width; use core::convert::TryFrom; use core::str::{from_utf8_unchecked, Bytes, FromStr}; #[cfg(feature = "serde")] use alloc::string::String; use alloc::fmt::{self, Display, Formatter}; use crate::UnitIncorrectError; #[cfg(feature = "serde")] use crate::serde::ser::{Serialize, Serializer}; #[cfg(feature = "serde")] use crate::serde::de::{Deserialize, Deserializer, Error as DeError, Visitor}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] /// The unit of bytes. pub enum ByteUnit { /// 1 B = 1 byte B, /// 1 KB = 1000 bytes (103) KB, /// 1 KiB = 1024 bytes (210) KiB, /// 1 MB = 1000000 bytes (106) MB, /// 1 MiB = 1048576 bytes (220) MiB, /// 1 GB = 1000000000 bytes (109) GB, /// 1 GiB = 1073741824 bytes (230) GiB, /// 1 TB = 1000000000000 bytes (1012) TB, /// 1 TiB = 1099511627776 bytes (240) TiB, /// 1 PB = 1000000000000000 bytes (1015) PB, /// 1 PiB = 1125899906842624 bytes (250) PiB, #[cfg(feature = "u128")] /// 1 EB = 1000000000000000000 bytes (1018) EB, #[cfg(feature = "u128")] /// 1 EiB = 1152921504606846976 bytes (260) EiB, #[cfg(feature = "u128")] /// 1 ZB = 1000000000000000000000 bytes (1021) ZB, #[cfg(feature = "u128")] /// 1 ZiB = 1180591620717411303424 bytes (270) ZiB, } impl ByteUnit { /// Get an instance of `ByteUnit` from a string slice. /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::ByteUnit; /// /// assert_eq!(ByteUnit::B, ByteUnit::from_str("").unwrap()); /// assert_eq!(ByteUnit::B, ByteUnit::from_str("b").unwrap()); /// assert_eq!(ByteUnit::B, ByteUnit::from_str("B").unwrap()); /// assert_eq!(ByteUnit::KB, ByteUnit::from_str("k").unwrap()); /// assert_eq!(ByteUnit::KB, ByteUnit::from_str("K").unwrap()); /// assert_eq!(ByteUnit::KiB, ByteUnit::from_str("Kib").unwrap()); /// assert_eq!(ByteUnit::MB, ByteUnit::from_str("mb").unwrap()); /// assert_eq!(ByteUnit::MiB, ByteUnit::from_str("mib").unwrap()); /// assert_eq!(ByteUnit::GB, ByteUnit::from_str("GB").unwrap()); /// assert_eq!(ByteUnit::GiB, ByteUnit::from_str("GiB").unwrap()); /// assert_eq!(ByteUnit::TB, ByteUnit::from_str("TB").unwrap()); /// assert_eq!(ByteUnit::TiB, ByteUnit::from_str("TIB").unwrap()); /// assert_eq!(ByteUnit::PB, ByteUnit::from_str("PB").unwrap()); /// assert_eq!(ByteUnit::PiB, ByteUnit::from_str("PiB").unwrap()); /// ``` #[allow(clippy::should_implement_trait)] pub fn from_str>(unit: S) -> Result { let s = unit.as_ref().trim(); let mut bytes = s.bytes(); read_xib(bytes.next(), bytes) } /// Use string slice to represent this `ByteUnit`. /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::ByteUnit; /// /// assert_eq!("B", ByteUnit::B.as_str()); /// assert_eq!("KB", ByteUnit::KB.as_str()); /// assert_eq!("KiB", ByteUnit::KiB.as_str()); /// assert_eq!("MB", ByteUnit::MB.as_str()); /// assert_eq!("MiB", ByteUnit::MiB.as_str()); /// assert_eq!("GB", ByteUnit::GB.as_str()); /// assert_eq!("GiB", ByteUnit::GiB.as_str()); /// assert_eq!("TB", ByteUnit::TB.as_str()); /// assert_eq!("TiB", ByteUnit::TiB.as_str()); /// assert_eq!("PB", ByteUnit::PB.as_str()); /// assert_eq!("PiB", ByteUnit::PiB.as_str()); /// ``` #[inline] pub fn as_str(self) -> &'static str { match self { ByteUnit::B => "B", ByteUnit::KB => "KB", ByteUnit::KiB => "KiB", ByteUnit::MB => "MB", ByteUnit::MiB => "MiB", ByteUnit::GB => "GB", ByteUnit::GiB => "GiB", ByteUnit::TB => "TB", ByteUnit::TiB => "TiB", ByteUnit::PB => "PB", ByteUnit::PiB => "PiB", #[cfg(feature = "u128")] ByteUnit::EB => "EB", #[cfg(feature = "u128")] ByteUnit::EiB => "EiB", #[cfg(feature = "u128")] ByteUnit::ZB => "ZB", #[cfg(feature = "u128")] ByteUnit::ZiB => "ZiB", } } /// Get bytes represented by this `ByteUnit`. /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::ByteUnit; /// /// assert_eq!(1000000000000000000000, ByteUnit::ZB.get_unit_bytes()); /// assert_eq!(1152921504606846976, ByteUnit::EiB.get_unit_bytes()); /// ``` #[cfg(feature = "u128")] #[inline] pub fn get_unit_bytes(self) -> u128 { match self { ByteUnit::B => 1, ByteUnit::KB => n_kb_bytes!(), ByteUnit::KiB => n_kib_bytes!(), ByteUnit::MB => n_mb_bytes!(), ByteUnit::MiB => n_mib_bytes!(), ByteUnit::GB => n_gb_bytes!(), ByteUnit::GiB => n_gib_bytes!(), ByteUnit::TB => n_tb_bytes!(), ByteUnit::TiB => n_tib_bytes!(), ByteUnit::PB => n_pb_bytes!(), ByteUnit::PiB => n_pib_bytes!(), ByteUnit::EB => n_eb_bytes!(), ByteUnit::EiB => n_eib_bytes!(), ByteUnit::ZB => n_zb_bytes!(), ByteUnit::ZiB => n_zib_bytes!(), } } /// Get bytes represented by this `ByteUnit`. /// /// ``` /// extern crate byte_unit; /// /// use byte_unit::ByteUnit; /// /// assert_eq!(1024, ByteUnit::KiB.get_unit_bytes()); /// assert_eq!(1000000000, ByteUnit::GB.get_unit_bytes()); /// ``` #[cfg(not(feature = "u128"))] #[inline] pub fn get_unit_bytes(self) -> u64 { match self { ByteUnit::B => 1, ByteUnit::KB => n_kb_bytes!(), ByteUnit::KiB => n_kib_bytes!(), ByteUnit::MB => n_mb_bytes!(), ByteUnit::MiB => n_mib_bytes!(), ByteUnit::GB => n_gb_bytes!(), ByteUnit::GiB => n_gib_bytes!(), ByteUnit::TB => n_tb_bytes!(), ByteUnit::TiB => n_tib_bytes!(), ByteUnit::PB => n_pb_bytes!(), ByteUnit::PiB => n_pib_bytes!(), } } } impl Display for ByteUnit { #[inline] fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { f.write_str(self.as_str()) } } impl AsRef for ByteUnit { #[inline] fn as_ref(&self) -> &str { self.as_str() } } impl TryFrom<&str> for ByteUnit { type Error = UnitIncorrectError; #[inline] fn try_from(s: &str) -> Result { ByteUnit::from_str(s) } } impl FromStr for ByteUnit { type Err = UnitIncorrectError; #[inline] fn from_str(s: &str) -> Result { ByteUnit::from_str(s) } } #[inline] pub(crate) fn get_char_from_bytes(e: u8, mut bytes: Bytes) -> char { let width = unsafe { utf8_width::get_width_assume_valid(e) }; let mut char_bytes = [e; 4]; if width > 1 { for e in char_bytes[1..].iter_mut().take(width - 1) { *e = bytes.next().unwrap(); } } let char_str = unsafe { from_utf8_unchecked(&char_bytes[..width]) }; char::from_str(char_str).unwrap() } pub(crate) fn read_xib(e: Option, mut bytes: Bytes) -> Result { match e { Some(e) => { match e.to_ascii_uppercase() { b'B' => { match bytes.next() { Some(e) => { Err(UnitIncorrectError { character: get_char_from_bytes(e, bytes), expected_characters: &[], also_expect_no_character: false, }) } None => Ok(ByteUnit::B), } } b'K' => { if read_ib(bytes)? { Ok(ByteUnit::KiB) } else { Ok(ByteUnit::KB) } } b'M' => { if read_ib(bytes)? { Ok(ByteUnit::MiB) } else { Ok(ByteUnit::MB) } } b'G' => { if read_ib(bytes)? { Ok(ByteUnit::GiB) } else { Ok(ByteUnit::GB) } } b'T' => { if read_ib(bytes)? { Ok(ByteUnit::TiB) } else { Ok(ByteUnit::TB) } } b'P' => { if read_ib(bytes)? { Ok(ByteUnit::PiB) } else { Ok(ByteUnit::PB) } } #[cfg(feature = "u128")] b'E' => { if read_ib(bytes)? { Ok(ByteUnit::EiB) } else { Ok(ByteUnit::EB) } } #[cfg(feature = "u128")] b'Z' => { if read_ib(bytes)? { Ok(ByteUnit::ZiB) } else { Ok(ByteUnit::ZB) } } _ => { #[cfg(feature = "u128")] { Err(UnitIncorrectError { character: get_char_from_bytes(e, bytes), expected_characters: &['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z'], also_expect_no_character: true, }) } #[cfg(not(feature = "u128"))] { Err(UnitIncorrectError { character: get_char_from_bytes(e, bytes), expected_characters: &['B', 'K', 'M', 'G', 'T', 'P'], also_expect_no_character: true, }) } } } } None => Ok(ByteUnit::B), } } fn read_ib(mut bytes: Bytes) -> Result { match bytes.next() { Some(e) => { match e.to_ascii_uppercase() { b'I' => { match bytes.next() { Some(e) => { match e.to_ascii_uppercase() { b'B' => Ok(true), _ => { Err(UnitIncorrectError { character: get_char_from_bytes(e, bytes), expected_characters: &['B'], also_expect_no_character: false, }) } } } None => Ok(true), } } b'B' => { match bytes.next() { Some(e) => { Err(UnitIncorrectError { character: get_char_from_bytes(e, bytes), expected_characters: &[], also_expect_no_character: false, }) } None => Ok(false), } } _ => { Err(UnitIncorrectError { character: get_char_from_bytes(e, bytes), expected_characters: &['B', 'i'], also_expect_no_character: false, }) } } } None => Ok(false), } } #[cfg(feature = "serde")] impl Serialize for ByteUnit { #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(self.as_str()) } } #[cfg(feature = "serde")] impl<'de> Deserialize<'de> for ByteUnit { #[inline] fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct ByteUnitVisitor; impl<'de> Visitor<'de> for ByteUnitVisitor { type Value = ByteUnit; #[inline] fn expecting(&self, f: &mut Formatter) -> Result<(), fmt::Error> { f.write_str("a byte unit such as \"B\", \"KB\" or \"MiB\"") } #[inline] fn visit_str(self, v: &str) -> Result where E: DeError, { ByteUnit::from_str(v).map_err(DeError::custom) } #[inline] fn visit_string(self, v: String) -> Result where E: DeError, { ByteUnit::from_str(v.as_str()).map_err(DeError::custom) } } deserializer.deserialize_any(ByteUnitVisitor) } } byte-unit-4.0.13/src/lib.rs000064400000000000000000000075150072674642500135740ustar 00000000000000/*! # Byte Unit A library for interaction with units of bytes. The units are **B** for 1 byte, **KB** for 1000 bytes, **KiB** for 1024 bytes, **MB** for 1000000 bytes, **MiB** for 1048576 bytes, etc, and up to **ZiB** which is 1180591620717411303424 bytes. The data type for storing the size of bytes is `u128` by default, but can also be changed to `u64` by disabling the default features (it will also cause the highest supported unit down to **PiB**). ## Usage ### Macros There are `n_*_bytes` macros can be used. The star `*` means the unit. For example, `n_gb_bytes` can be used to get a **n-GB** value in bytes. ```rust #[macro_use] extern crate byte_unit; let result = n_gb_bytes!(4); assert_eq!(4000000000, result); ``` You may need to assign a primitive type if the `n` is not an integer. ```rust #[macro_use] extern crate byte_unit; let result = n_gb_bytes!(2.5, f64); assert_eq!(2500000000, result); ``` ### Byte The `Byte` structure can be used for representing a size of bytes. The `from_str` associated function can parse any **SIZE** string and return a `Byte` instance in common usage. The format of a **SIZE** string is like "123", "123KiB" or "50.84 MB". ```rust extern crate byte_unit; use byte_unit::Byte; let result = Byte::from_str("50.84 MB").unwrap(); assert_eq!(50840000, result.get_bytes()); ``` You can also use the `from_bytes` and `from_unit` associated functions to create a `Byte` instance. ```rust extern crate byte_unit; use byte_unit::Byte; let result = Byte::from_bytes(1500000); assert_eq!(1500000, result.get_bytes()); ``` ```rust extern crate byte_unit; use byte_unit::{Byte, ByteUnit}; let result = Byte::from_unit(1500f64, ByteUnit::KB).unwrap(); assert_eq!(1500000, result.get_bytes()); ``` ### AdjustedByte To change the unit of a `Byte` instance, you can use the `get_adjusted_unit` method. ```rust extern crate byte_unit; use byte_unit::{Byte, ByteUnit}; let byte = Byte::from_str("123KiB").unwrap(); let adjusted_byte = byte.get_adjusted_unit(ByteUnit::KB); assert_eq!("125.95 KB", adjusted_byte.to_string()); ``` To change the unit of a `Byte` instance automatically and appropriately, you can use the `get_appropriate_unit` method. ```rust extern crate byte_unit; use byte_unit::Byte; let byte = Byte::from_bytes(1500000); let adjusted_byte = byte.get_appropriate_unit(false); assert_eq!("1.50 MB", adjusted_byte.to_string()); ``` ```rust extern crate byte_unit; use byte_unit::Byte; let byte = Byte::from_bytes(1500000); let adjusted_byte = byte.get_appropriate_unit(true); assert_eq!("1.43 MiB", adjusted_byte.to_string()); ``` The number of fractional digits created by the `to_string` method of a `AdjustedByte` instance is `2` unless the `ByteUnit` is `B`. To change the number of fractional digits in the formatted string, you can use the `format` method instead. ```rust extern crate byte_unit; use byte_unit::Byte; let byte = Byte::from_bytes(1500000); let adjusted_byte = byte.get_appropriate_unit(false); assert_eq!("1.5 MB", adjusted_byte.format(1)); ``` ## No Std Disable the default features to compile this crate without std. ```toml [dependencies.byte-unit] version = "*" default-features = false features = ["u128"] ``` ## Serde Support Enable the `serde` feature to support the serde framework. ```toml [dependencies.byte-unit] version = "*" features = ["serde"] ``` */ #![cfg_attr(not(feature = "std"), no_std)] #[macro_use] extern crate alloc; #[cfg(feature = "serde")] #[macro_use] extern crate serde; #[cfg(feature = "u128")] #[macro_use] mod u128; #[cfg(not(feature = "u128"))] #[macro_use] mod u64; #[macro_use] mod macros; mod adjusted_byte; mod byte; mod byte_error; mod byte_unit; #[cfg(feature = "u128")] pub use self::u128::*; #[cfg(not(feature = "u128"))] pub use self::u64::*; pub use self::byte_unit::*; pub use adjusted_byte::*; pub use byte::*; pub use byte_error::*; byte-unit-4.0.13/src/macros.rs000064400000000000000000000202270072674642500143050ustar 00000000000000/// Convert n KB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_kb_bytes!(4); /// /// assert_eq!(4000, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_kb_bytes!(2.5, f64); /// /// assert_eq!(2500, result); /// ``` #[macro_export] macro_rules! n_kb_bytes { () => { $crate::KILOBYTE }; ($x:expr) => { $crate::n_kb_bytes($x) }; ($x:expr, $t:ty) => { $crate::_bytes_as!($x * ($crate::MEGABYTE as $t)) / $crate::KILOBYTE }; } /// Convert n KiB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_kib_bytes!(4); /// /// assert_eq!(4096, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_kib_bytes!(2.5, f64); /// /// assert_eq!(2560, result); /// ``` #[macro_export] macro_rules! n_kib_bytes { () => { $crate::KIBIBYTE }; ($x:expr) => { $crate::n_kib_bytes($x) }; ($x:expr, $t:ty) => { $crate::_bytes_as!($x * ($crate::MEBIBYTE as $t)) / $crate::KIBIBYTE }; } /// Convert n MB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_mb_bytes!(4); /// /// assert_eq!(4000000, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_mb_bytes!(2.5, f64); /// /// assert_eq!(2500000, result); /// ``` #[macro_export] macro_rules! n_mb_bytes { () => { $crate::MEGABYTE }; ($x:expr) => { $crate::n_mb_bytes($x) }; ($x:expr, $t:ty) => { $crate::_bytes_as!($x * ($crate::MEGABYTE as $t)) }; } /// Convert n MiB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_mib_bytes!(4); /// /// assert_eq!(4194304, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_mib_bytes!(2.5, f64); /// /// assert_eq!(2621440, result); /// ``` #[macro_export] macro_rules! n_mib_bytes { () => { $crate::MEBIBYTE }; ($x:expr) => { $crate::n_mib_bytes($x) }; ($x:expr, $t:ty) => { $crate::_bytes_as!($x * ($crate::MEBIBYTE as $t)) }; } /// Convert n GB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_gb_bytes!(4); /// /// assert_eq!(4000000000, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_gb_bytes!(2.5, f64); /// /// assert_eq!(2500000000, result); /// ``` #[macro_export] macro_rules! n_gb_bytes { () => { $crate::GIGABYTE }; ($x:expr) => { $crate::n_gb_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_kb_bytes($crate::_bytes_as!($x * ($crate::MEGABYTE as $t))) }; } /// Convert n GiB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_gib_bytes!(4); /// /// assert_eq!(4294967296, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_gib_bytes!(2.5, f64); /// /// assert_eq!(2684354560, result); /// ``` #[macro_export] macro_rules! n_gib_bytes { () => { $crate::GIBIBYTE }; ($x:expr) => { $crate::n_gib_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_kib_bytes($crate::_bytes_as!($x * ($crate::MEBIBYTE as $t))) }; } /// Convert n TB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_tb_bytes!(4); /// /// assert_eq!(4000000000000, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_tb_bytes!(2.5, f64); /// /// assert_eq!(2500000000000, result); /// ``` #[macro_export] macro_rules! n_tb_bytes { () => { $crate::TERABYTE }; ($x:expr) => { $crate::n_tb_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_mb_bytes($crate::_bytes_as!($x * ($crate::MEGABYTE as $t))) }; } /// Convert n TiB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_tib_bytes!(4); /// /// assert_eq!(4398046511104, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_tib_bytes!(2.5, f64); /// /// assert_eq!(2748779069440, result); /// ``` #[macro_export] macro_rules! n_tib_bytes { () => { $crate::TEBIBYTE }; ($x:expr) => { $crate::n_tib_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_mib_bytes($crate::_bytes_as!($x * ($crate::MEBIBYTE as $t))) }; } /// Convert n PB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_pb_bytes!(4); /// /// assert_eq!(4000000000000000, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_pb_bytes!(2.5, f64); /// /// assert_eq!(2500000000000000, result); /// ``` #[macro_export] macro_rules! n_pb_bytes { () => { $crate::PETABYTE }; ($x:expr) => { $crate::n_pb_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_gb_bytes($crate::_bytes_as!($x * ($crate::MEGABYTE as $t))) }; } /// Convert n PiB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_pib_bytes!(4); /// /// assert_eq!(4503599627370496, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_pib_bytes!(2.5, f64); /// /// assert_eq!(2814749767106560, result); /// ``` #[macro_export] macro_rules! n_pib_bytes { () => { $crate::PEBIBYTE }; ($x:expr) => { $crate::n_pib_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_gib_bytes($crate::_bytes_as!($x * ($crate::MEBIBYTE as $t))) }; } /// Convert n EB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_eb_bytes!(4); /// /// assert_eq!(4000000000000000000, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_eb_bytes!(2.5, f64); /// /// assert_eq!(2500000000000000000, result); /// ``` #[cfg(feature = "u128")] #[macro_export] macro_rules! n_eb_bytes { () => { $crate::EXABYTE }; ($x:expr) => { $crate::n_eb_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_tb_bytes($crate::_bytes_as!($x * ($crate::MEGABYTE as $t))) }; } /// Convert n EiB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_eib_bytes!(4); /// /// assert_eq!(4611686018427387904, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_eib_bytes!(2.5, f64); /// /// assert_eq!(2882303761517117440, result); /// ``` #[cfg(feature = "u128")] #[macro_export] macro_rules! n_eib_bytes { () => { $crate::EXBIBYTE }; ($x:expr) => { $crate::n_eib_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_tib_bytes($crate::_bytes_as!($x * ($crate::MEBIBYTE as $t))) }; } /// Convert n ZB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_zb_bytes!(4); /// /// assert_eq!(4000000000000000000000, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_zb_bytes!(2.5, f64); /// /// assert_eq!(2500000000000000000000, result); /// ``` #[cfg(feature = "u128")] #[macro_export] macro_rules! n_zb_bytes { () => { $crate::ZETTABYTE }; ($x:expr) => { $crate::n_zb_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_pb_bytes($crate::_bytes_as!($x * ($crate::MEGABYTE as $t))) }; } /// Convert n ZiB to bytes. /// /// ## Examples /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_zib_bytes!(4); /// /// assert_eq!(4722366482869645213696, result); /// ``` /// /// ``` /// extern crate byte_unit; /// /// let result = byte_unit::n_zib_bytes!(2.5, f64); /// /// assert_eq!(2951479051793528258560, result); /// ``` #[cfg(feature = "u128")] #[macro_export] macro_rules! n_zib_bytes { () => { $crate::ZEBIBYTE }; ($x:expr) => { $crate::n_zib_bytes($x) }; ($x:expr, $t:ty) => { $crate::n_pib_bytes($crate::_bytes_as!($x * ($crate::MEBIBYTE as $t))) }; } byte-unit-4.0.13/src/u128/constants.rs000064400000000000000000000042350072674642500155350ustar 00000000000000/// KB pub const KILOBYTE: u128 = 1_000; /// KiB pub const KIBIBYTE: u128 = 1 << 10; /// MB pub const MEGABYTE: u128 = 1_000_000; /// MiB pub const MEBIBYTE: u128 = 1 << 20; /// GB pub const GIGABYTE: u128 = 1_000_000_000; /// GiB pub const GIBIBYTE: u128 = 1 << 30; /// TB pub const TERABYTE: u128 = 1_000_000_000_000; /// TiB pub const TEBIBYTE: u128 = 1 << 40; /// PB pub const PETABYTE: u128 = 1_000_000_000_000_000; /// PiB pub const PEBIBYTE: u128 = 1 << 50; /// EB pub const EXABYTE: u128 = 1_000_000_000_000_000_000; /// EiB pub const EXBIBYTE: u128 = 1 << 60; /// ZB pub const ZETTABYTE: u128 = 1_000_000_000_000_000_000_000; /// ZiB pub const ZEBIBYTE: u128 = 1 << 70; /// Convert n KB to bytes. #[inline] pub const fn n_kb_bytes(bytes: u128) -> u128 { bytes * KILOBYTE } /// Convert n KiB to bytes. #[inline] pub const fn n_kib_bytes(bytes: u128) -> u128 { bytes * KIBIBYTE } /// Convert n MB to bytes. #[inline] pub const fn n_mb_bytes(bytes: u128) -> u128 { bytes * MEGABYTE } /// Convert n MiB to bytes. #[inline] pub const fn n_mib_bytes(bytes: u128) -> u128 { bytes * MEBIBYTE } /// Convert n GB to bytes. #[inline] pub const fn n_gb_bytes(bytes: u128) -> u128 { bytes * GIGABYTE } /// Convert n GiB to bytes. #[inline] pub const fn n_gib_bytes(bytes: u128) -> u128 { bytes * GIBIBYTE } /// Convert n TB to bytes. #[inline] pub const fn n_tb_bytes(bytes: u128) -> u128 { bytes * TERABYTE } /// Convert n TiB to bytes. #[inline] pub const fn n_tib_bytes(bytes: u128) -> u128 { bytes * TEBIBYTE } /// Convert n PB to bytes. #[inline] pub const fn n_pb_bytes(bytes: u128) -> u128 { bytes * PETABYTE } /// Convert n PiB to bytes. #[inline] pub const fn n_pib_bytes(bytes: u128) -> u128 { bytes * PEBIBYTE } /// Convert n EB to bytes. #[inline] pub const fn n_eb_bytes(bytes: u128) -> u128 { bytes * EXABYTE } /// Convert n EiB to bytes. #[inline] pub const fn n_eib_bytes(bytes: u128) -> u128 { bytes * EXBIBYTE } /// Convert n ZB to bytes. #[inline] pub const fn n_zb_bytes(bytes: u128) -> u128 { bytes * ZETTABYTE } /// Convert n ZiB to bytes. #[inline] pub const fn n_zib_bytes(bytes: u128) -> u128 { bytes * ZEBIBYTE } byte-unit-4.0.13/src/u128/mod.rs000064400000000000000000000002160072674642500142730ustar 00000000000000mod constants; pub use constants::*; #[doc(hidden)] #[macro_export] macro_rules! _bytes_as { ($x:expr) => { $x as u128 }; } byte-unit-4.0.13/src/u64/constants.rs000064400000000000000000000027650072674642500154620ustar 00000000000000/// KB pub const KILOBYTE: u64 = 1_000; /// KiB pub const KIBIBYTE: u64 = 1 << 10; /// MB pub const MEGABYTE: u64 = 1_000_000; /// MiB pub const MEBIBYTE: u64 = 1 << 20; /// GB pub const GIGABYTE: u64 = 1_000_000_000; /// GiB pub const GIBIBYTE: u64 = 1 << 30; /// TB pub const TERABYTE: u64 = 1_000_000_000_000; /// TiB pub const TEBIBYTE: u64 = 1 << 40; /// PB pub const PETABYTE: u64 = 1_000_000_000_000_000; /// PiB pub const PEBIBYTE: u64 = 1 << 50; /// Convert n KB to bytes. #[inline] pub const fn n_kb_bytes(bytes: u64) -> u64 { bytes * KILOBYTE } /// Convert n KiB to bytes. #[inline] pub const fn n_kib_bytes(bytes: u64) -> u64 { bytes * KIBIBYTE } /// Convert n MB to bytes. #[inline] pub const fn n_mb_bytes(bytes: u64) -> u64 { bytes * MEGABYTE } /// Convert n MiB to bytes. #[inline] pub const fn n_mib_bytes(bytes: u64) -> u64 { bytes * MEBIBYTE } /// Convert n GB to bytes. #[inline] pub const fn n_gb_bytes(bytes: u64) -> u64 { bytes * GIGABYTE } /// Convert n GiB to bytes. #[inline] pub const fn n_gib_bytes(bytes: u64) -> u64 { bytes * GIBIBYTE } /// Convert n TB to bytes. #[inline] pub const fn n_tb_bytes(bytes: u64) -> u64 { bytes * TERABYTE } /// Convert n TiB to bytes. #[inline] pub const fn n_tib_bytes(bytes: u64) -> u64 { bytes * TEBIBYTE } /// Convert n PB to bytes. #[inline] pub const fn n_pb_bytes(bytes: u64) -> u64 { bytes * PETABYTE } /// Convert n PiB to bytes. #[inline] pub const fn n_pib_bytes(bytes: u64) -> u64 { bytes * PEBIBYTE } byte-unit-4.0.13/src/u64/mod.rs000064400000000000000000000002150072674642500142110ustar 00000000000000mod constants; pub use constants::*; #[doc(hidden)] #[macro_export] macro_rules! _bytes_as { ($x:expr) => { $x as u64 }; }