vaz_lib 0.1.0

vazLIB is a small library made for those who just don't want to fuddle with complex stuff.
Documentation
pub fn term() -> console::Term {
    console::Term::stdout()
}
pub fn clear() {
    let _ = std::process::Command::new("clear").status();
}
pub fn write(term: &console::Term, s: &dyn std::fmt::Display) {
    let _ = term.write_str(format!("{}", s).as_str());
}
pub fn getch(term: &console::Term) -> char {
    term.read_char().unwrap()
}

pub fn getche(term: &console::Term, ch: Option<char>) -> char {
    let new_ch = term.read_char().unwrap();
    let _ = match ch {
        Some(c) => {
            if new_ch != '\n' {
                term.write_str(c.to_string().as_str())
            } else {
                term.write_str(" ".to_string().as_str())
            }
        }
        None => term.write_str(new_ch.to_string().as_str()),
    };

    return new_ch;
}
pub fn bulk_getche(term: &console::Term, ch: Option<char>, n: u8) -> Vec<char> {
    let mut chars: Vec<char> = Vec::new();
    for _ in 0..n {
        let x = getche(term, ch);
        if x == '\n' {
            break;
        } else {
            chars.push(x);
        }
    }
    chars
}
pub fn getk(term: &console::Term) -> console::Key {
    term.read_key().unwrap()
}

pub fn get_string(term: &console::Term, ch: Option<char>, n: u8) -> String {
    use console::Key;
    let mut charlist: Vec<char> = Vec::new();

    let mut index: u8 = 0;
    while index < n + 1 {
        let x = getk(term);
        match x {
            Key::Enter => break,
            Key::Char(s) => {
                if index == n {
                } else if index == charlist.len() as u8 {
                    charlist.push(s);
                    let _ = term.write_str(
                        format!(
                            "{}",
                            match ch {
                                Some(c) => c,
                                None => s,
                            }
                        )
                        .as_str(),
                    );
                    index += 1;
                } else {
                    charlist[index as usize] = s;
                    let _ = term.write_str(
                        format!(
                            "{}",
                            match ch {
                                Some(c) => c,
                                None => s,
                            }
                        )
                        .as_str(),
                    );
                    index += 1;
                }
            }
            Key::ArrowLeft => {
                if index != 0 {
                    let _ = term.write_str("\x1b[D");
                    index -= 1;
                }
            }
            Key::ArrowRight => {
                if index != charlist.len() as u8 {
                    let _ = term.write_str("\x1b[C");
                    index += 1;
                }
            }
            Key::Backspace => {
                if index == charlist.len() as u8 && index != 0 {
                    charlist.pop();
                    let _ = term.write_str("\x1b[D \x1b[D");
                    index -= 1;
                }
            }

            _ => (),
        }
    }

    charlist.iter().fold(String::new(), |x, y| {
        let mut z = x;
        z.push(*y);
        z
    })
}
pub fn menu(term: &console::Term, items: Vec<&dyn core::fmt::Display>) -> u32 {
    use console::Key;
    let mut i = 0;
    let mut new_i = 0;
    for item in &items {
        let _ = term.write_str(format!("{}\n", item).as_str());
    }
    for _ in &items {
        let _ = term.write_str("\x1b[A\r");
    }

    loop {
        let _ = term.write_str(
            format!(
                "\r\x1b[2K\x1b[38;2;0;0;0m\x1b[48;2;255;255;255m\
                    {}\
                    \x1b[m\x1b[?25l\
                    ",
                items[i]
            )
            .as_str(),
        );
        let key = getk(term);

        match key {
            Key::Enter => {
                break;
            }
            Key::ArrowUp => {
                if i != 0 {
                    new_i -= 1;
                }
            }
            Key::ArrowDown => {
                if i < items.len() - 1 {
                    new_i += 1;
                }
            }
            _ => (),
        }
        if new_i != i {
            let _ = term.write_str("\x1b[2K\r");
            let _ = term.write_str(format!("{}", items[i]).as_str());
            for _ in i..items.len() {
                let _ = term.write_str("\x1b[B");
            }
            for _ in new_i..items.len() {
                let _ = term.write_str("\x1b[A");
            }
        }
        i = new_i;
    }

    for _ in 0..(items.len() - i) {
        let _ = term.write_str("\x1b[B\x1b[2K\r");
    }
    for _ in &items {
        let _ = term.write_str("\x1b[A\x1b[2K\r");
    }

    let _ = term.write_str("\x1b[?25h");

    i as u32
}