bitbottle 0.10.0

a modern archive file format
Documentation
use std::fmt::Write as _; // import without risk of name clashing
use crate::{FileAtlas, FileList, HashType};
use crate::cli::*;

/// Common code for rendering a pretty text version of a file atlas.
pub fn display_atlas_filename(atlas: &FileAtlas) -> String {
    let is_symlink = atlas.symlink_target.is_some();
    let (format_dir, folder_trail) = match (atlas.is_folder, is_symlink) {
        (true, _) => ('d', "/".to_string()),
        (_, true) => ('l', format!(" -> {}", atlas.symlink_target.as_ref().unwrap().to_string_lossy())),
        (_, _) => ('-', "".to_string()),
    };

    let user_group = if atlas.user.is_empty() && atlas.group.is_empty() {
        ""
    } else {
        &format!("{}  {}  ", pad_truncate(&atlas.user, 8), pad_truncate(&atlas.group, 8))
    };

    format!(
        "    {}{}  {}{:>5}  {}  {}{}",
        format_dir, format_perms(atlas.perms as usize), user_group,
        if atlas.is_folder || is_symlink { String::default() } else { to_binary_si(atlas.size as f64) },
        format_datetime(atlas.mtime_ns / 1_000_000_000),
        atlas.normalized_path.to_string_lossy(), folder_trail,
    )
}

pub fn display_file_header(hash_type: Option<HashType>, file_list: &FileList, orig_size: Option<u64>) -> String {
    let mut size_str: String = format!("{}B", to_binary_si(file_list.total_size() as f64));
    if let Some(orig_size) = orig_size {
        write!(size_str, " -> {}B", to_binary_si(orig_size as f64)).unwrap();
    }
    let mut ret = format!(
        "Bitbottle: {} files, {} blocks, {}",
        file_list.total_file_count(), file_list.blocks.len(), size_str
    );
    if let Some(hash_type) = hash_type {
        ret += &format!(" ({hash_type:?} hash)");
    }
    ret
}

pub fn display_file_list(hash_type: Option<HashType>, file_list: &FileList, orig_size: Option<u64>) -> Vec<String> {
    let mut rv = vec![];
    for atlas in &file_list.files {
        rv.push(display_atlas_filename(&atlas.borrow()));
    }
    rv.push(display_file_header(hash_type, file_list, orig_size));
    rv
}