bitbottle 0.10.0

a modern archive file format
Documentation
use chrono::{Datelike, DateTime, Local};


// not sure where to put this!
pub fn truncate(s: &str, limit: usize) -> String {
    if s.len() <= limit { return s.to_string(); }
    s[0 .. limit - 1].to_string() + ""
}

pub fn lpad_truncate(s: &str, limit: usize) -> String {
    format!("{:>limit$}", truncate(s, limit), limit = limit)
}

pub fn pad_truncate(s: &str, limit: usize) -> String {
    format!("{:limit$}", truncate(s, limit), limit = limit)
}

pub fn indent_line(s: &str, count: usize) -> String {
    format!("{:>limit$}{}", "", s, limit = count)
}

pub fn indent(lines: Vec<String>, count: usize) -> Vec<String> {
    lines.iter().map(|s| indent_line(s, count)).collect()
}

pub fn format_datetime(epoch_sec: i64) -> String {
    let datetime = DateTime::from_timestamp(epoch_sec, 0).unwrap_or_default().naive_local();
    datetime.format("%Y-%m-%d %H:%M:%S").to_string()
}

// returns a string of 8 or 10 chars
pub fn format_relative_time(epoch_sec: i64) -> String {
    let datetime = DateTime::from_timestamp(epoch_sec, 0).unwrap_or_default().naive_local();
    let now = Local::now().naive_local();
    let ago = now.signed_duration_since(datetime);
    if ago.num_hours() < 12 || (ago.num_hours() < 24 && now.date().day() == datetime.date().day()) {
        datetime.format("%H:%M:%S").to_string()
    } else {
        datetime.format("%Y-%m-%d").to_string()
    }
}

fn format_perms_3(perms: usize) -> String {
    [ [ '-', 'r' ][(perms >> 2) & 1] , [ '-', 'w' ][(perms >> 1) & 1] , [ '-', 'x' ][perms & 1] ].iter().collect()
}

pub fn format_perms(perms: usize) -> String {
    format_perms_3(perms >> 6) + &format_perms_3(perms >> 3) + &format_perms_3(perms)
}