1use std::convert::Infallible;
2use std::fmt;
3
4use humansize::{DECIMAL, ISizeFormatter, ToF64};
5
6/// Returns adequate string representation (in KB, ..) of number of bytes
7///
8/// ## Example
9/// ```
10/// # use rinja::Template;
11/// #[derive(Template)]
12/// #[template(
13/// source = "Filesize: {{ size_in_bytes|filesizeformat }}.",
14/// ext = "html"
15/// )]
16/// struct Example {
17/// size_in_bytes: u64,
18/// }
19///
20/// let tmpl = Example { size_in_bytes: 1_234_567 };
21/// assert_eq!(tmpl.to_string(), "Filesize: 1.23 MB.");
22/// ```
23#[inline]
24pub fn filesizeformat(b: &impl ToF64) -> Result<FilesizeFormatFilter, Infallible> {
25 Ok(FilesizeFormatFilter(b.to_f64()))
26}
27
28#[derive(Debug, Clone, Copy)]
29pub struct FilesizeFormatFilter(f64);
30
31impl fmt::Display for FilesizeFormatFilter {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 f.write_fmt(format_args!("{}", ISizeFormatter::new(self.0, &DECIMAL)))
34 }
35}
36
37#[test]
38fn test_filesizeformat() {
39 assert_eq!(filesizeformat(&0).unwrap().to_string(), "0 B");
40 assert_eq!(filesizeformat(&999u64).unwrap().to_string(), "999 B");
41 assert_eq!(filesizeformat(&1000i32).unwrap().to_string(), "1 kB");
42 assert_eq!(filesizeformat(&1023).unwrap().to_string(), "1.02 kB");
43 assert_eq!(filesizeformat(&1024usize).unwrap().to_string(), "1.02 kB");
44}
45