diff --git a/Cargo.lock b/Cargo.lock index 195b79a5..9e0bcde3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -655,6 +655,7 @@ dependencies = [ "handlebars", "http", "http-auth-basic", + "humansize", "hyper", "hyper-rustls", "lazy_static", @@ -684,6 +685,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + [[package]] name = "hyper" version = "0.14.27" @@ -803,6 +813,12 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "linux-raw-sys" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index fbd60172..0568e61c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,9 +49,15 @@ serde = { version = "1.0.192", features = ["derive"] } serde_json = "1.0.108" structopt = { version = "0.3.26", default-features = false } termcolor = "1.1.3" -tokio = { version = "1.29.1", features = ["fs", "rt-multi-thread", "signal", "macros"] } +tokio = { version = "1.29.1", features = [ + "fs", + "rt-multi-thread", + "signal", + "macros", +] } tokio-rustls = "0.23.4" toml = "0.7.6" +humansize = "2.1.3" [dev-dependencies] criterion = { version = "0.5.1", features = ["async_tokio", "html_reports"] } diff --git a/src/addon/file_server/directory_entry.rs b/src/addon/file_server/directory_entry.rs index 200a32d9..472e3045 100644 --- a/src/addon/file_server/directory_entry.rs +++ b/src/addon/file_server/directory_entry.rs @@ -9,8 +9,7 @@ use std::cmp::{Ord, Ordering}; pub struct DirectoryEntry { pub(crate) display_name: String, pub(crate) is_dir: bool, - pub(crate) size: String, - pub(crate) len: u64, + pub(crate) size_bytes: u64, pub(crate) entry_path: String, pub(crate) date_created: Option>, pub(crate) date_modified: Option>, diff --git a/src/addon/file_server/mod.rs b/src/addon/file_server/mod.rs index a0f53793..020f1dff 100644 --- a/src/addon/file_server/mod.rs +++ b/src/addon/file_server/mod.rs @@ -7,6 +7,7 @@ mod scoped_file_system; use chrono::{DateTime, Local}; pub use file::{File, FILE_BUFFER_SIZE}; +use humansize::{format_size, DECIMAL}; pub use scoped_file_system::{Directory, Entry, ScopedFileSystem}; use anyhow::{Context, Result}; @@ -20,7 +21,6 @@ use std::path::{Component, Path, PathBuf}; use std::str::FromStr; use std::sync::Arc; -use crate::utils::fmt::format_bytes; use crate::utils::url_encode::{decode_uri, encode_uri, PERCENT_ENCODE_SET}; use self::directory_entry::{BreadcrumbItem, DirectoryEntry, DirectoryIndex, Sort}; @@ -68,6 +68,9 @@ impl<'a> FileServer { }); handlebars.register_helper("date", Box::new(date)); + handlebars_helper!(size: |bytes: u64| format_size(bytes, DECIMAL)); + handlebars.register_helper("size", Box::new(size)); + handlebars_helper!(sort_name: |sort: Sort| sort == Sort::Name); handlebars.register_helper("sort_name", Box::new(sort_name)); @@ -264,8 +267,7 @@ impl<'a> FileServer { .context("Unable to gather file name into a String")? .to_string(), is_dir: metadata.is_dir(), - size: format_bytes(metadata.len() as f64), - len: metadata.len(), + size_bytes: metadata.len(), entry_path: FileServer::make_dir_entry_link(&root_dir, &entry.path()), date_created, date_modified, @@ -278,7 +280,7 @@ impl<'a> FileServer { SortBy::Name => { directory_entries.sort_by_key(|entry| entry.display_name.clone()); } - SortBy::Size => directory_entries.sort_by_key(|entry| entry.len), + SortBy::Size => directory_entries.sort_by_key(|entry| entry.size_bytes), SortBy::DateCreated => { directory_entries.sort_by_key(|entry| entry.date_created) } diff --git a/src/addon/file_server/template/explorer.hbs b/src/addon/file_server/template/explorer.hbs index f600e63d..75c7939d 100644 --- a/src/addon/file_server/template/explorer.hbs +++ b/src/addon/file_server/template/explorer.hbs @@ -223,7 +223,7 @@ {{/if}} {{display_name}} - {{size}} + {{size size_bytes}} {{date date_created}} {{date date_modified}} diff --git a/src/utils/fmt.rs b/src/utils/fmt.rs deleted file mode 100644 index 0b0cf4ff..00000000 --- a/src/utils/fmt.rs +++ /dev/null @@ -1,38 +0,0 @@ -/// Byte size units -const BYTE_SIZE_UNIT: [&str; 9] = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; - -/// Calculates the format of the `Bytes` by converting `bytes` to the -/// corresponding unit and returns a human readable size label -pub fn format_bytes(bytes: f64) -> String { - if bytes == 0. { - return String::from("0 Bytes"); - } - - let i = (bytes.log10() / 1024_f64.log10()).floor(); - let value = bytes / 1024_f64.powf(i); - - format!("{:.2} {}", value, BYTE_SIZE_UNIT[i as usize]) -} - -#[cfg(test)] -mod tests { - use std::vec; - - use super::format_bytes; - - #[test] - fn formats_bytes() { - let byte_sizes = vec![1024., 1048576., 1073741824., 1099511627776.]; - - let expect = vec![ - String::from("1.00 KB"), - String::from("1.00 MB"), - String::from("1.00 GB"), - String::from("1.00 TB"), - ]; - - for (idx, size) in byte_sizes.into_iter().enumerate() { - assert_eq!(format_bytes(size), expect[idx]); - } - } -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 305d97cc..46d14a32 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,4 +1,3 @@ pub mod error; -pub mod fmt; pub mod signal; pub mod url_encode;