92 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
use std::ops::Mul;
 | 
						|
 | 
						|
#[derive(thiserror::Error, Debug)]
 | 
						|
enum FilesSizeUtilsError {
 | 
						|
    #[error("UnitConvertError: {0}")]
 | 
						|
    UnitConvert(String),
 | 
						|
}
 | 
						|
 | 
						|
/// Holds a data size, convertible in any form
 | 
						|
#[derive(
 | 
						|
    serde::Serialize,
 | 
						|
    serde::Deserialize,
 | 
						|
    Copy,
 | 
						|
    Clone,
 | 
						|
    Debug,
 | 
						|
    Eq,
 | 
						|
    PartialEq,
 | 
						|
    PartialOrd,
 | 
						|
    Ord,
 | 
						|
    Default,
 | 
						|
)]
 | 
						|
pub struct FileSize(usize);
 | 
						|
 | 
						|
impl FileSize {
 | 
						|
    pub const fn from_bytes(size: usize) -> Self {
 | 
						|
        Self(size)
 | 
						|
    }
 | 
						|
 | 
						|
    pub const fn from_mb(mb: usize) -> Self {
 | 
						|
        Self(mb * 1000 * 1000)
 | 
						|
    }
 | 
						|
 | 
						|
    pub const fn from_gb(gb: usize) -> Self {
 | 
						|
        Self(gb * 1000 * 1000 * 1000)
 | 
						|
    }
 | 
						|
 | 
						|
    /// Convert size unit to MB
 | 
						|
    pub fn from_size_unit(unit: &str, value: usize) -> anyhow::Result<Self> {
 | 
						|
        let fact = match unit {
 | 
						|
            "bytes" | "b" => 1f64,
 | 
						|
            "KB" => 1000f64,
 | 
						|
            "MB" => 1000f64 * 1000f64,
 | 
						|
            "GB" => 1000f64 * 1000f64 * 1000f64,
 | 
						|
            "TB" => 1000f64 * 1000f64 * 1000f64 * 1000f64,
 | 
						|
 | 
						|
            "k" | "KiB" => 1024f64,
 | 
						|
            "M" | "MiB" => 1024f64 * 1024f64,
 | 
						|
            "G" | "GiB" => 1024f64 * 1024f64 * 1024f64,
 | 
						|
            "T" | "TiB" => 1024f64 * 1024f64 * 1024f64 * 1024f64,
 | 
						|
 | 
						|
            _ => {
 | 
						|
                return Err(
 | 
						|
                    FilesSizeUtilsError::UnitConvert(format!("Unknown size unit: {unit}")).into(),
 | 
						|
                );
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        Ok(Self((value as f64).mul(fact).ceil() as usize))
 | 
						|
    }
 | 
						|
 | 
						|
    /// Get file size as bytes
 | 
						|
    pub fn as_bytes(&self) -> usize {
 | 
						|
        self.0
 | 
						|
    }
 | 
						|
 | 
						|
    /// Get file size as megabytes
 | 
						|
    pub fn as_mb(&self) -> usize {
 | 
						|
        self.0 / (1000 * 1000)
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#[cfg(test)]
 | 
						|
mod tests {
 | 
						|
    use crate::utils::file_size_utils::FileSize;
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn convert_units_mb() {
 | 
						|
        assert_eq!(FileSize::from_size_unit("MB", 1).unwrap().as_mb(), 1);
 | 
						|
        assert_eq!(FileSize::from_size_unit("MB", 1000).unwrap().as_mb(), 1000);
 | 
						|
        assert_eq!(
 | 
						|
            FileSize::from_size_unit("GB", 1000).unwrap().as_mb(),
 | 
						|
            1000 * 1000
 | 
						|
        );
 | 
						|
        assert_eq!(FileSize::from_size_unit("GB", 1).unwrap().as_mb(), 1000);
 | 
						|
        assert_eq!(FileSize::from_size_unit("GiB", 3).unwrap().as_mb(), 3221);
 | 
						|
        assert_eq!(
 | 
						|
            FileSize::from_size_unit("KiB", 488281).unwrap().as_mb(),
 | 
						|
            499
 | 
						|
        );
 | 
						|
    }
 | 
						|
}
 |