#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), allow(clippy::unnecessary_cast))]
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
#![cfg_attr(feature = "std", doc = "```")]
#[cfg(feature = "std")]
pub mod fmt;
#[cfg(feature = "std")]
mod from_str;
pub mod ops;
#[cfg(feature = "serde")]
mod serde;
#[cfg(test)]
mod tests;
#[cfg(test)]
mod tests_nostd;
pub use crate::consts::*;
#[cfg(feature = "std")]
pub use crate::fmt::{Base, SizeFormatter, Style};
#[cfg(feature = "std")]
pub use crate::from_str::ParseSizeError;
use crate::sealed::AsIntermediate;
#[cfg(feature = "std")]
type Intermediate = f64;
#[cfg(not(feature = "std"))]
type Intermediate = i64;
#[cfg(feature = "std")]
const DEFAULT_BASE: Base = Base::Base2;
#[cfg(feature = "std")]
const DEFAULT_STYLE: Style = Style::Default;
mod sealed {
use super::Intermediate;
pub trait AsIntermediate: Sized {
fn as_(self) -> Intermediate;
}
macro_rules! as_intermediate {
($type:ty) => {
impl AsIntermediate for $type {
fn as_(self) -> Intermediate {
use core::mem::size_of;
const SIGNED_MAX: $type = Intermediate::MAX as $type;
if cfg!(not(feature = "std")) && <$type>::MIN == 0 as $type && size_of::<Intermediate>() >= size_of::<$type>() && self > SIGNED_MAX {
Intermediate::MAX
} else {
self as Intermediate
}
}
}
};
}
as_intermediate!(u8);
as_intermediate!(u16);
as_intermediate!(u32);
as_intermediate!(u64);
as_intermediate!(usize);
as_intermediate!(i8);
as_intermediate!(i16);
as_intermediate!(i32);
as_intermediate!(i64);
as_intermediate!(isize);
#[cfg(feature = "std")]
as_intermediate!(f32);
#[cfg(feature = "std")]
as_intermediate!(f64);
}
pub mod consts {
#![allow(non_upper_case_globals)]
pub const BYTE: i64 = 1;
pub const KILOBYTE: i64 = 1000 * BYTE;
pub const MEGABYTE: i64 = 1000 * KILOBYTE;
pub const GIGABYTE: i64 = 1000 * MEGABYTE;
pub const TERABYTE: i64 = 1000 * GIGABYTE;
pub const PETABYTE: i64 = 1000 * TERABYTE;
pub const EXABYTE: i64 = 1000 * PETABYTE;
pub const B: i64 = BYTE;
pub const KB: i64 = KILOBYTE;
pub const MB: i64 = MEGABYTE;
pub const GB: i64 = GIGABYTE;
pub const TB: i64 = TERABYTE;
pub const PB: i64 = PETABYTE;
pub const EB: i64 = EXABYTE;
pub const KIBIBYTE: i64 = 1 << 10;
pub const MEBIBYTE: i64 = 1 << 20;
pub const GIBIBYTE: i64 = 1 << 30;
pub const TEBIBYTE: i64 = 1 << 40;
pub const PEBIBYTE: i64 = 1 << 50;
pub const EXBIBYTE: i64 = 1 << 60;
pub const KiB: i64 = KIBIBYTE;
pub const MiB: i64 = MEBIBYTE;
pub const GiB: i64 = GIBIBYTE;
pub const TiB: i64 = TEBIBYTE;
pub const PiB: i64 = PEBIBYTE;
pub const EiB: i64 = EXBIBYTE;
}
#[cfg_attr(not(feature = "std"), doc = "```ignore")]
#[cfg_attr(feature = "std", doc = "```")]
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
pub struct Size {
bytes: i64,
}
impl Size {
pub const fn from_const(bytes: i64) -> Self {
Self { bytes }
}
pub fn from_bytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: value.as_() as i64,
}
}
pub fn from_kilobytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * KILOBYTE as Intermediate) as i64,
}
}
pub fn from_megabytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * MEGABYTE as Intermediate) as i64,
}
}
pub fn from_gigabytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * GIGABYTE as Intermediate) as i64,
}
}
pub fn from_terabytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * TERABYTE as Intermediate) as i64,
}
}
pub fn from_petabytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * PETABYTE as Intermediate) as i64,
}
}
pub fn from_exabytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * EXABYTE as Intermediate) as i64,
}
}
#[inline]
pub fn from_kb<T: AsIntermediate>(value: T) -> Self {
Self::from_kilobytes(value)
}
#[inline]
pub fn from_mb<T: AsIntermediate>(value: T) -> Self {
Self::from_megabytes(value)
}
#[inline]
pub fn from_gb<T: AsIntermediate>(value: T) -> Self {
Self::from_gigabytes(value)
}
#[inline]
pub fn from_tb<T: AsIntermediate>(value: T) -> Self {
Self::from_terabytes(value)
}
#[inline]
pub fn from_pb<T: AsIntermediate>(value: T) -> Self {
Self::from_petabytes(value)
}
#[inline]
pub fn from_eb<T: AsIntermediate>(value: T) -> Self {
Self::from_exabytes(value)
}
pub fn from_kibibytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * KIBIBYTE as Intermediate) as i64,
}
}
pub fn from_mebibytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * MEBIBYTE as Intermediate) as i64,
}
}
pub fn from_gibibytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * GIBIBYTE as Intermediate) as i64,
}
}
pub fn from_tebibytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * TEBIBYTE as Intermediate) as i64,
}
}
pub fn from_pebibytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * PEBIBYTE as Intermediate) as i64,
}
}
pub fn from_exbibytes<T: AsIntermediate>(value: T) -> Self {
Self {
bytes: (value.as_() * EXBIBYTE as Intermediate) as i64,
}
}
#[inline]
pub fn from_kib<T: AsIntermediate>(value: T) -> Self {
Self::from_kibibytes(value)
}
#[inline]
pub fn from_mib<T: AsIntermediate>(value: T) -> Self {
Self::from_mebibytes(value)
}
#[inline]
pub fn from_gib<T: AsIntermediate>(value: T) -> Self {
Self::from_gibibytes(value)
}
#[inline]
pub fn from_tib<T: AsIntermediate>(value: T) -> Self {
Self::from_tebibytes(value)
}
#[inline]
pub fn from_pib<T: AsIntermediate>(value: T) -> Self {
Self::from_pebibytes(value)
}
#[inline]
pub fn from_eib<T: AsIntermediate>(value: T) -> Self {
Self::from_exbibytes(value)
}
}
impl Size {
#[inline]
pub const fn bytes(&self) -> i64 {
self.bytes
}
}
#[doc(hidden)]
impl Size {
#![allow(non_snake_case)]
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_bytes() instead")]
pub fn Bytes<T: AsIntermediate>(t: T) -> Self {
Self::from_bytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_kibibytes() instead")]
pub fn Kibibytes<T: AsIntermediate>(t: T) -> Self {
Self::from_kibibytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_kilobytes() instead")]
pub fn Kilobytes<T: AsIntermediate>(t: T) -> Self {
Self::from_kilobytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_mebibytes() instead")]
pub fn Mebibytes<T: AsIntermediate>(t: T) -> Self {
Self::from_mebibytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_megabytes() instead")]
pub fn Megabytes<T: AsIntermediate>(t: T) -> Self {
Self::from_megabytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_gibibytes() instead")]
pub fn Gibibytes<T: AsIntermediate>(t: T) -> Self {
Self::from_gibibytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_gigabytes() instead")]
pub fn Gigabytes<T: AsIntermediate>(t: T) -> Self {
Self::from_gigabytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_tebibytes() instead")]
pub fn Tebibytes<T: AsIntermediate>(t: T) -> Self {
Self::from_tebibytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_terabytes() instead")]
pub fn Terabytes<T: AsIntermediate>(t: T) -> Self {
Self::from_terabytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_pebibytes() instead")]
pub fn Pebibytes<T: AsIntermediate>(t: T) -> Self {
Self::from_pebibytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_petabytes() instead")]
pub fn Petabytes<T: AsIntermediate>(t: T) -> Self {
Self::from_petabytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_exbibytes() instead")]
pub fn Exbibytes<T: AsIntermediate>(t: T) -> Self {
Self::from_exbibytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_exabytes() instead")]
pub fn Exabytes<T: AsIntermediate>(t: T) -> Self {
Self::from_exabytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_bytes() instead")]
pub fn B<T: AsIntermediate>(t: T) -> Self {
Self::from_bytes(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_kib() instead")]
pub fn KiB<T: AsIntermediate>(t: T) -> Self {
Self::from_kib(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_kb() instead")]
pub fn KB<T: AsIntermediate>(t: T) -> Self {
Self::from_kb(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_mib() instead")]
pub fn MiB<T: AsIntermediate>(t: T) -> Self {
Self::from_mib(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_mb() instead")]
pub fn MB<T: AsIntermediate>(t: T) -> Self {
Self::from_mb(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_gib() instead")]
pub fn GiB<T: AsIntermediate>(t: T) -> Self {
Self::from_gib(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_gb() instead")]
pub fn GB<T: AsIntermediate>(t: T) -> Self {
Self::from_gb(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_tib() instead")]
pub fn TiB<T: AsIntermediate>(t: T) -> Self {
Self::from_tib(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_tb() instead")]
pub fn TB<T: AsIntermediate>(t: T) -> Self {
Self::from_tb(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_pib() instead")]
pub fn PiB<T: AsIntermediate>(t: T) -> Self {
Self::from_pib(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_pb() instead")]
pub fn PB<T: AsIntermediate>(t: T) -> Self {
Self::from_pb(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_eib() instead")]
pub fn EiB<T: AsIntermediate>(t: T) -> Self {
Self::from_eib(t)
}
#[inline]
#[deprecated(since = "0.3.0", note = "Use Size::from_eb() instead")]
pub fn EB<T: AsIntermediate>(t: T) -> Self {
Self::from_eb(t)
}
}
impl core::fmt::Debug for Size {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(fmt, "{} bytes", self.bytes())
}
}