sll 0.1.3

A simple logging library.
Documentation
use colored::Colorize;
use std::io;
use std::io::Write;

#[allow(dead_code)]
pub enum LogLevel {
    CRITICAL,
    ERROR,
    WARNING,
    INFO,
    NOTICE,
    DEBUG,
}

pub struct Spinner {
    state: usize,
}
// ⣾⣽⣻⢿⡿⣟⣯⣷
impl Spinner {
    pub fn new() -> Spinner {
        Spinner { state: 0 }
    }
    pub fn update(&mut self) {
        self.state += 1;
        self.state %= 12;
        let c: &str = [
            "", "", "⠋⠁", "⠉⠉", "⠈⠙", "", "", "", "⢀⣠", "⣀⣀", "⣄⡀", "",
        ][self.state];
        print!("\x08\x08\x08{} ", c);
        io::stdout().flush().expect("stdout flush failed");
    }
    pub fn release(&self) {
        println!("\x08\x08\x08⣏⣹");
    }
}

pub struct Progress {
    total: usize,
    current: usize,
    last: usize,
}

impl Progress {
    pub fn new(total: usize, current: usize) -> Progress {
        Progress {
            total,
            current,
            last: 0,
        }
    }
    pub fn update(&mut self, n: usize) {
        self.current += n;
        if (self.current + 1) * 20 / self.total > self.last {
            self.display();
            io::stdout().flush().expect("Failed to flush stdout");
        }
    }
    pub fn display(&self) {
        let mut line = "\r[".to_string();
        line += &"#".repeat((self.current + 1) * 20 / self.total);
        line += &" ".repeat(20 - (self.current + 1) * 20 / self.total);
        line += "]";
        print!("{}", line);
    }
    pub fn release(&self) {
        println!();
    }
}

pub fn log(msg: &str, level: LogLevel) {
    let level_tag: String;
    match level {
        LogLevel::CRITICAL => level_tag = format!("<{}>", "CRITICAL".bold().yellow().on_red()),
        LogLevel::ERROR => level_tag = format!("<{}>", "ERROR".bold().bright_red()),
        LogLevel::WARNING => level_tag = format!("<{}>", "WARNING".bold().bright_yellow()),
        LogLevel::INFO => level_tag = format!("[{}]", "INFO".bold().green()),
        LogLevel::DEBUG => level_tag = format!("({})", "DEBUG".bold().bright_green()),
        LogLevel::NOTICE => level_tag = format!("({})", "NOTICE".bold().bright_black()),
    }
    println!("{}: {}", level_tag, msg);
}

pub fn section(msg: &str, depth: u8) {
    println!("{} {} {}", "   ".repeat(depth.into()), "::".blue(), msg);
}

pub fn task(msg: &str, depth: u8) {
    println!("{} {} {}", "   ".repeat(depth.into()), " =>".green(), msg);
}

pub fn prompt(msg: &str, depth: u8) -> String {
    print!("{} {} {}: ", "   ".repeat(depth.into()), " ?".yellow(), msg);
    let _ = io::stdout().flush();
    let mut buffer = String::new();
    let stdin = io::stdin();
    match stdin.read_line(&mut buffer) {
        Ok(_n) => {}
        Err(_e) => {}
    }
    return buffer;
}

#[macro_export]
macro_rules! section {
    ($msg: expr) => {
        section($msg, 0);
    };
    ($msg: expr, $depth: expr) => {
        section($msg, $depth);
    };
}

#[macro_export]
macro_rules! task {
    ($msg: expr) => {
        task($msg, 0);
    };
    ($msg: expr, $depth: expr) => {
        task($msg, $depth);
    };
}

#[macro_export]
macro_rules! prompt {
    ($msg: expr) => {
        prompt($msg, 0);
    };
    ($msg: expr, $depth: expr) => {
        prompt($msg, $depth);
    };
}

#[macro_export]
macro_rules! log {
    ($msg: expr, $level: expr) => {
        log($msg, $level);
    };
    ($msg: expr) => {
        log($msg, LogLevel::DEBUG);
    };
}

pub fn main() {}