liteboxfs 0.2.0

A modern POSIX filesystem in a SQLite database
Documentation
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())
    }
}