use super::MutTxn;
use fs_representation::{RepoRoot, RepoPath, in_repo_root};
use patch::Record;
use record::RecordState;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use Result;
#[derive(Debug)]
pub enum ChangeType {
Modified,
New,
Del,
Move(Rc<RepoPath<PathBuf>>),
}
impl ChangeType {
pub fn short(&self) -> &str {
match *self {
ChangeType::Modified => "M",
ChangeType::New => "A",
ChangeType::Del => "D",
ChangeType::Move(_) => "→",
}
}
pub fn long(&self) -> &str {
match *self {
ChangeType::Modified => "modified:",
ChangeType::New => "new file:",
ChangeType::Del => "deleted:",
ChangeType::Move(_) => "moved:",
}
}
}
pub fn unrecorded_changes<T: rand::Rng>(
txn: &mut MutTxn<T>,
repo_root: &RepoRoot<impl AsRef<Path>>,
branch: &String,
) -> Result<Vec<(Rc<RepoPath<PathBuf>>, ChangeType)>> {
let mut record = RecordState::new();
let branch = txn.open_branch(branch)?;
txn.record(
super::DiffAlgorithm::default(),
&mut record,
&branch,
repo_root,
&in_repo_root()
)?;
txn.commit_branch(branch)?;
let (changes, _) = record.finish();
let mut ret = vec![];
let mut current_file = None;
for change in changes.iter() {
match *change {
Record::Change { ref file, .. } => {
if current_file.clone().map_or(true, |f| &f != file) {
ret.push((file.clone(), ChangeType::Modified));
current_file = Some(file.clone());
}
}
Record::FileAdd { ref name, .. } => {
let file = Rc::new(name.clone());
current_file = Some(file.clone());
ret.push((file.clone(), ChangeType::New));
}
Record::FileDel { ref name, .. } => {
let file = Rc::new(name.clone());
current_file = Some(file.clone());
ret.push((file.clone(), ChangeType::Del));
}
Record::FileMove { ref new_name, .. } => {
let file = Rc::new(new_name.clone());
current_file = Some(file.clone());
ret.push((file.clone(), ChangeType::Move(file)));
}
}
}
Ok(ret)
}