use {
crate::{
app::*,
file_sum::FileSum,
task_sync::Dam,
},
std::path::{
Path,
PathBuf,
},
};
#[derive(Default, Debug)]
pub struct Stage {
version: usize,
paths: Vec<PathBuf>,
}
impl Stage {
pub fn contains(
&self,
path: &Path,
) -> bool {
self.paths.iter().any(|p| p == path)
}
pub fn is_empty(&self) -> bool {
self.paths.is_empty()
}
pub fn add(
&mut self,
path: PathBuf,
) -> bool {
if self.contains(&path) {
false
} else {
self.version += 1;
self.paths.push(path);
true
}
}
pub fn remove(
&mut self,
path: &Path,
) -> bool {
if let Some(pos) = self.paths.iter().position(|p| p == path) {
self.version += 1;
self.paths.remove(pos);
true
} else {
false
}
}
pub fn remove_idx(
&mut self,
idx: usize,
) {
if idx < self.paths.len() {
self.version += 1;
self.paths.remove(idx);
}
}
pub fn clear(&mut self) {
self.version += 1;
self.paths.clear();
}
pub fn paths(&self) -> &[PathBuf] {
&self.paths
}
pub fn refresh(&mut self) {
let len_before = self.paths.len();
self.paths.retain(|p| p.exists());
if self.paths.len() != len_before {
self.version += 1;
}
}
pub fn len(&self) -> usize {
self.paths.len()
}
pub fn version(&self) -> usize {
self.version
}
pub fn compute_sum(
&self,
dam: &Dam,
con: &AppContext,
) -> Option<FileSum> {
let mut sum = FileSum::zero();
for path in &self.paths {
if path.is_dir() {
let dir_sum = FileSum::from_dir(path, dam, con);
if let Some(dir_sum) = dir_sum {
sum += dir_sum;
} else {
return None; }
} else {
sum += FileSum::from_file(path);
}
}
Some(sum)
}
pub fn to_selections(&self) -> Vec<Selection<'_>> {
self.paths
.iter()
.map(|path| Selection {
path,
line: 0,
stype: SelectionType::from(path),
is_exe: false,
})
.collect()
}
}