use std::{
fmt::{self, Debug, Display},
path::{Path, PathBuf},
};
pub const KIB: usize = 1024;
pub const MIB: usize = 1024 * KIB;
pub const TEST_INPUTS: [TestInput; 3] = [
TestInput { len: 8 * KIB },
TestInput { len: 2 * MIB },
TestInput { len: 512 * MIB },
];
#[derive(Debug)]
pub struct TestInput {
pub len: usize,
}
impl Display for TestInput {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.len < MIB {
write!(f, "{} KiB", self.len / KIB)
} else {
write!(f, "{} MiB", self.len / MIB)
}
}
}
#[derive(Debug)]
pub struct TreeSpec {
pub depth: u32,
pub branches: u32,
}
impl TreeSpec {
fn create_tree_inner(&self, paths: &mut Vec<PathBuf>, parent: &Path, level: u32) {
if level == self.depth {
return;
}
for file_index in 1..=self.branches {
let new_path = parent.join(file_index.to_string());
self.create_tree_inner(paths, &new_path, level + 1);
paths.push(new_path);
}
}
fn total_nodes(&self) -> u32 {
(self.branches.pow(self.depth + 1) - 1) / (self.branches - 1)
}
pub fn create_tree(&self) -> Vec<PathBuf> {
let mut paths = Vec::new();
self.create_tree_inner(&mut paths, Path::new("/"), 0);
paths.sort_unstable_by_key(|path| path.components().count());
paths
}
}
impl Display for TreeSpec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} files", self.total_nodes())
}
}