extern crate colored; use colored::*; use std::io::{self, Write}; use std::process::Command; #[inline] /// Convenience method to check if `condition` is the next substring of `from` fn match_ahead(condition: &str, from: &str) -> bool { condition.len() <= from.len() && &from[..condition.len()] == condition } /// Takes an input string, and a seperator, and returns slices of the original string /// Up to, and then after the seperator is reached fn take_until<'a>(until: &str, take_from: &'a str) -> (&'a str, &'a str) { let bound = take_from.len(); let slice = until.len(); let mut pos = slice; while pos <= bound && &take_from[pos - slice..pos] != until { pos += 1; } (&take_from[..pos - slice], &take_from[pos..]) } /// Counts the occurances of `count` until `until` occurs in `take_from` /// Returns the count, and the remainder of `take_from` fn count_until<'a>(count: &str, until: &str, take_from: &'a str) -> (u32, &'a str) { let bound = take_from.len(); let slice = until.len(); let l = count.len(); let mut pos = if slice > l { slice } else { l }; let mut counter = 0; while pos <= bound && &take_from[pos - slice..pos] != until { if &take_from[pos - l..pos] == count { counter += 1; } pos += 1; } (counter, &take_from[pos..]) } fn main() { if let Ok(output) = Command::new("git").arg("status").output() { if output.status.success() { let output = String::from_utf8_lossy(&output.stdout); let mut stdout = io::stdout(); let (_, output) = take_until("On branch", &output); let (branch_name, output) = take_until("\n", &output); let _ = write!(stdout, "on {}{}", "".bright_purple().bold(), branch_name); //TODO: +- from remote let (_, mut output) = take_until("\n\n", &output); if match_ahead("Changes to be committed:", &output) { let (_, s_output) = take_until("\n\n", &output); let (staged_count, s_output) = count_until("\n", "\n\n", &s_output); let _ = write!(stdout, " {}{}", "+".bright_green().bold(), staged_count); output = s_output; } if match_ahead("Changes not staged for commit:", &output) { let (_, s_output) = take_until("\n\n", &output); let (mod_count, s_output) = count_until("\n", "\n\n", &s_output); let _ = write!(stdout, " {}{}", "*".bright_yellow().bold(), mod_count); output = s_output; } if match_ahead("Untracked files:", &output) { let (_, s_output) = take_until("\n\n", &output); let (untr_count, s_output) = count_until("\n", "\n\n", &s_output); let _ = write!(stdout, " {}{}", "+".bright_blue().bold(), untr_count); let _output = s_output; } } } }