use crate::error::{MyError, MyResult};
use git2::Status;
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct GitFlags {
pub everything: bool,
pub cached: bool,
pub added: bool,
pub modified: bool,
pub renamed: bool,
pub untracked: bool,
pub ignored: bool,
}
impl GitFlags {
pub fn from_str(value: &str) -> MyResult<Self> {
let mut flags = Self::default();
for ch in value.chars() {
match ch {
'x' => flags.everything = true,
'c' => flags.cached = true,
'a' => flags.added = true,
'm' => flags.modified = true,
'r' => flags.renamed = true,
'u' => flags.untracked = true,
'i' => flags.ignored = true,
_ => return Err(MyError::create_clap("git", ch)),
}
}
Ok(flags)
}
pub fn with_everything(mut self, everything: bool) -> Self {
self.everything = everything;
self
}
pub fn with_cached(mut self, cached: bool) -> Self {
self.cached = cached;
self
}
pub fn with_added(mut self, added: bool) -> Self {
self.added = added;
self
}
pub fn with_modified(mut self, modified: bool) -> Self {
self.modified = modified;
self
}
pub fn with_renamed(mut self, renamed: bool) -> Self {
self.renamed = renamed;
self
}
pub fn with_untracked(mut self, untracked: bool) -> Self {
self.untracked = untracked;
self
}
pub fn with_ignored(mut self, ignored: bool) -> Self {
self.ignored = ignored;
self
}
pub fn test_allowed(&self, status: &Status) -> Option<Self> {
if self.is_allowed(status) {
let flags = Self::default()
.with_added(status.is_index_new())
.with_modified(status.is_index_modified() || status.is_wt_modified())
.with_renamed(status.is_index_renamed() || status.is_wt_renamed())
.with_untracked(status.is_wt_new())
.with_ignored(status.is_ignored());
Some(flags)
} else {
None
}
}
fn is_allowed(&self, status: &Status) -> bool {
if self.everything {
return true;
}
if self.cached && !status.is_ignored() && !status.is_wt_new() {
return true;
}
if self.added && status.is_index_new() {
return true;
}
if self.modified && (status.is_index_modified() || status.is_wt_modified()) {
return true;
}
if self.renamed && (status.is_index_renamed() || status.is_wt_renamed()) {
return true;
}
if self.untracked && status.is_wt_new() {
return true;
}
if self.ignored && status.is_ignored() {
return true;
}
false
}
}
#[cfg(test)]
mod tests {
use crate::git::flags::GitFlags;
use git2::Status;
#[test]
fn test_files_are_included_with_cached_flag() {
let flags = GitFlags::default().with_cached(true);
assert_eq!(true, flags.is_allowed(&Status::INDEX_NEW));
assert_eq!(true, flags.is_allowed(&Status::INDEX_MODIFIED));
assert_eq!(true, flags.is_allowed(&Status::INDEX_RENAMED));
assert_eq!(true, flags.is_allowed(&Status::INDEX_DELETED));
assert_eq!(true, flags.is_allowed(&Status::INDEX_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
assert_eq!(true, flags.is_allowed(&Status::WT_MODIFIED));
assert_eq!(true, flags.is_allowed(&Status::WT_RENAMED));
assert_eq!(true, flags.is_allowed(&Status::WT_DELETED));
assert_eq!(true, flags.is_allowed(&Status::WT_TYPECHANGE));
assert_eq!(true, flags.is_allowed(&Status::WT_UNREADABLE));
assert_eq!(false, flags.is_allowed(&Status::IGNORED));
assert_eq!(true, flags.is_allowed(&Status::CONFLICTED));
}
#[test]
fn test_files_are_included_with_added_flag() {
let flags = GitFlags::default().with_added(true);
assert_eq!(true, flags.is_allowed(&Status::INDEX_NEW));
assert_eq!(false, flags.is_allowed(&Status::INDEX_MODIFIED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
assert_eq!(false, flags.is_allowed(&Status::WT_MODIFIED));
assert_eq!(false, flags.is_allowed(&Status::WT_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
assert_eq!(false, flags.is_allowed(&Status::IGNORED));
assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
}
#[test]
fn test_files_are_included_with_modified_flag() {
let flags = GitFlags::default().with_modified(true);
assert_eq!(false, flags.is_allowed(&Status::INDEX_NEW));
assert_eq!(true, flags.is_allowed(&Status::INDEX_MODIFIED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
assert_eq!(true, flags.is_allowed(&Status::WT_MODIFIED));
assert_eq!(false, flags.is_allowed(&Status::WT_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
assert_eq!(false, flags.is_allowed(&Status::IGNORED));
assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
}
#[test]
fn test_files_are_included_with_renamed_flag() {
let flags = GitFlags::default().with_renamed(true);
assert_eq!(false, flags.is_allowed(&Status::INDEX_NEW));
assert_eq!(false, flags.is_allowed(&Status::INDEX_MODIFIED));
assert_eq!(true, flags.is_allowed(&Status::INDEX_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
assert_eq!(false, flags.is_allowed(&Status::WT_MODIFIED));
assert_eq!(true, flags.is_allowed(&Status::WT_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
assert_eq!(false, flags.is_allowed(&Status::IGNORED));
assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
}
#[test]
fn test_files_are_included_with_untracked_flag() {
let flags = GitFlags::default().with_untracked(true);
assert_eq!(false, flags.is_allowed(&Status::INDEX_NEW));
assert_eq!(false, flags.is_allowed(&Status::INDEX_MODIFIED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
assert_eq!(true, flags.is_allowed(&Status::WT_NEW));
assert_eq!(false, flags.is_allowed(&Status::WT_MODIFIED));
assert_eq!(false, flags.is_allowed(&Status::WT_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
assert_eq!(false, flags.is_allowed(&Status::IGNORED));
assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
}
#[test]
fn test_files_are_included_with_ignored_flag() {
let flags = GitFlags::default().with_ignored(true);
assert_eq!(false, flags.is_allowed(&Status::INDEX_NEW));
assert_eq!(false, flags.is_allowed(&Status::INDEX_MODIFIED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
assert_eq!(false, flags.is_allowed(&Status::WT_MODIFIED));
assert_eq!(false, flags.is_allowed(&Status::WT_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
assert_eq!(true, flags.is_allowed(&Status::IGNORED));
assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
}
#[test]
fn test_files_are_included_with_multiple_flags() {
let flags = GitFlags::default().with_added(true).with_modified(true).with_renamed(true);
assert_eq!(true, flags.is_allowed(&Status::INDEX_NEW));
assert_eq!(true, flags.is_allowed(&Status::INDEX_MODIFIED));
assert_eq!(true, flags.is_allowed(&Status::INDEX_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
assert_eq!(true, flags.is_allowed(&Status::WT_MODIFIED));
assert_eq!(true, flags.is_allowed(&Status::WT_RENAMED));
assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
assert_eq!(false, flags.is_allowed(&Status::IGNORED));
assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
}
}