use core::marker::Destruct;
use super::ByteSize;
use crate::traits::BaseByteSize;
use crate::traits::ExaByteSize;
use crate::traits::GigaByteSize;
use crate::traits::KiloByteSize;
use crate::traits::MegaByteSize;
use crate::traits::PetaByteSize;
use crate::traits::TeraByteSize;
impl<T: BaseByteSize> ByteSize<T> {
pub const fn map<F>(self, f: F) -> Self
where
F: [const] FnOnce(T) -> T + [const] Destruct,
{
ByteSize(f(self.0))
}
#[inline(always)]
pub const fn as_b(&self) -> f64
where
T: [const] BaseByteSize,
{
self.0.to_f64()
}
}
impl<T: KiloByteSize> ByteSize<T> {
#[inline(always)]
pub const fn kb(size: T) -> Self
where
T: [const] KiloByteSize,
{
ByteSize(size * T::KB)
}
#[inline(always)]
pub const fn kib(size: T) -> Self
where
T: [const] KiloByteSize,
{
ByteSize(size * T::KIB)
}
#[inline(always)]
pub const fn as_kb(&self) -> f64
where
T: [const] KiloByteSize,
{
self.0.to_f64() / T::KB.to_f64()
}
#[inline(always)]
pub const fn as_kib(&self) -> f64
where
T: [const] KiloByteSize,
{
self.0.to_f64() / T::KIB.to_f64()
}
}
impl<T: MegaByteSize> ByteSize<T> {
#[inline(always)]
pub const fn mb(size: T) -> Self
where
T: [const] MegaByteSize,
{
ByteSize(size * T::MB)
}
#[inline(always)]
pub const fn mib(size: T) -> Self
where
T: [const] MegaByteSize,
{
ByteSize(size * T::MIB)
}
#[inline(always)]
pub const fn as_mb(&self) -> f64
where
T: [const] MegaByteSize,
{
self.0.to_f64() / T::MB.to_f64()
}
#[inline(always)]
pub const fn as_mib(&self) -> f64
where
T: [const] MegaByteSize,
{
self.0.to_f64() / T::MIB.to_f64()
}
}
impl<T: GigaByteSize> ByteSize<T> {
#[inline(always)]
pub const fn gb(size: T) -> Self
where
T: [const] GigaByteSize,
{
ByteSize(size * T::GB)
}
#[inline(always)]
pub const fn gib(size: T) -> Self
where
T: [const] GigaByteSize,
{
ByteSize(size * T::GIB)
}
#[inline(always)]
pub const fn as_gb(&self) -> f64
where
T: [const] GigaByteSize,
{
self.0.to_f64() / T::GB.to_f64()
}
#[inline(always)]
pub const fn as_gib(&self) -> f64
where
T: [const] GigaByteSize,
{
self.0.to_f64() / T::GIB.to_f64()
}
}
impl<T: TeraByteSize> ByteSize<T> {
#[inline(always)]
pub const fn tb(size: T) -> Self
where
T: [const] TeraByteSize,
{
ByteSize(size * T::TB)
}
#[inline(always)]
pub const fn tib(size: T) -> Self
where
T: [const] TeraByteSize,
{
ByteSize(size * T::TIB)
}
#[inline(always)]
pub const fn as_tb(&self) -> f64
where
T: [const] TeraByteSize,
{
self.0.to_f64() / T::TB.to_f64()
}
#[inline(always)]
pub const fn as_tib(&self) -> f64
where
T: [const] TeraByteSize,
{
self.0.to_f64() / T::TIB.to_f64()
}
}
impl<T: PetaByteSize> ByteSize<T> {
#[inline(always)]
pub const fn pb(size: T) -> Self
where
T: [const] PetaByteSize,
{
ByteSize(size * T::PB)
}
#[inline(always)]
pub const fn pib(size: T) -> Self
where
T: [const] PetaByteSize,
{
ByteSize(size * T::PIB)
}
#[inline(always)]
pub const fn as_pb(&self) -> f64
where
T: [const] PetaByteSize,
{
self.0.to_f64() / T::PB.to_f64()
}
#[inline(always)]
pub const fn as_pib(&self) -> f64
where
T: [const] PetaByteSize,
{
self.0.to_f64() / T::PIB.to_f64()
}
}
impl<T: ExaByteSize> ByteSize<T> {
#[inline(always)]
pub const fn eb(size: T) -> Self
where
T: [const] ExaByteSize,
{
ByteSize(size * T::EB)
}
#[inline(always)]
pub const fn eib(size: T) -> Self
where
T: [const] ExaByteSize,
{
ByteSize(size * T::EIB)
}
#[inline(always)]
pub const fn as_eb(&self) -> f64
where
T: [const] ExaByteSize,
{
self.0.to_f64() / T::EB.to_f64()
}
#[inline(always)]
pub const fn as_eib(&self) -> f64
where
T: [const] ExaByteSize,
{
self.0.to_f64() / T::EIB.to_f64()
}
}
#[cfg(test)]
mod tests {
use super::ByteSize;
use crate::assert_close;
#[test]
fn infers_constructor_type_from_argument() {
assert_eq!(ByteSize::kib(16_u64), ByteSize::b(16 * 1_024));
assert_eq!(ByteSize::mib(16_u32), ByteSize::b(16 * 1_048_576));
}
#[test]
fn inferred_constructor_is_const() {
const SIZE: ByteSize<u64> = ByteSize::kib(16_u64);
assert_eq!(SIZE, ByteSize::b(16 * 1_024));
}
#[test]
fn inferred_accessors_are_const() {
const BYTES: f64 = ByteSize::b(16_u64).as_b();
const KIB: f64 = ByteSize::kib(16_u64).as_kib();
assert_close(BYTES, 16.0);
assert_close(KIB, 16.0);
}
#[test]
fn map_is_const() {
const SIZE: ByteSize<u64> = ByteSize::kib(4_u64).map(const |bytes| bytes + 64);
assert_eq!(SIZE, ByteSize::b(4_160));
}
}