extern crate regex;
use std::collections::HashMap;
use self::regex::{Regex, Captures};
#[derive(Debug)]
pub struct Branches {
pub branches: HashMap<String, Branch>,
pub current: String,
}
impl Branches {
pub fn current_branch(&self) -> Branch {
self.branches.get(&self.current).unwrap().clone()
}
pub fn is_current(&self, branch: &Branch) -> bool {
self.current == branch.name
}
pub fn list(&self) -> Vec<Branch> {
self.branches
.iter()
.map(|(_, branch)| branch.clone())
.collect()
}
}
#[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct Branch {
pub name: String,
pub last_commit: String,
pub last_commit_msg: String,
pub remote_branch_name: String,
}
impl Branch {
pub fn new_by_name(name: &str) -> Branch {
Branch {
name: name.to_string(),
last_commit: "".to_string(),
last_commit_msg: "".to_string(),
remote_branch_name: "".to_string(),
}
}
pub fn new(log: &str) -> Branch {
lazy_static! {
static ref LOG_REGEXP: Regex = Regex::new(r"(?P<name>\S+)\s+(?P<commit>[[:alnum:]]+)\s+(?:(?P<remote>\[.*?\])\s+)?(?P<msg>.*)").unwrap();
}
LOG_REGEXP.captures(log).map_or_else(|| panic!(format!("invalid branch log. : {}", log)), |c: Captures| {
Branch{
name: c.name("name").map_or("", |m| m.as_str()).to_owned(),
last_commit: c.name("commit").map_or("", |m| m.as_str()).to_owned(),
last_commit_msg: c.name("msg").map_or("", |m| m.as_str()).to_owned(),
remote_branch_name: c.name("remote").map_or("", |m| m.as_str()).to_owned(),
}
})
}
}
#[cfg(test)]
mod tests {
mod branches {
use std::collections::HashMap;
use super::super::*;
#[test]
fn current_branch() {
let mut map = HashMap::new();
map.insert("first".to_string(), Branch::new_by_name("first"));
let branch = Branch::new_by_name("second");
map.insert("second".to_string(), branch.clone());
let branches = Branches{ branches: map, current: "second".to_string()};
assert_eq!(branch, branches.current_branch());
}
#[test]
fn is_current() {
let mut map = HashMap::new();
let first = Branch::new_by_name("first");
map.insert("first".to_string(), first.clone());
let second = Branch::new_by_name("second");
map.insert("second".to_string(), second.clone());
let branches = Branches{ branches: map, current: second.name.clone()};
assert_eq!(false, branches.is_current(&first));
assert_eq!(true, branches.is_current(&second));
}
}
mod branch {
use super::super::*;
#[test]
fn new_branch() {
let log = "master 2d6953d [origin/master: behind 8] Merged in feature/presentation-material-ceres (pull request #287)";
let branch = Branch::new(log);
assert_eq!(Branch{
name: "master".to_string(),
last_commit: "2d6953d".to_string(),
last_commit_msg: "Merged in feature/presentation-material-ceres (pull request #287)".to_string(),
remote_branch_name: "[origin/master: behind 8]".to_string(),
}, branch);
}
}
}