libpijul 0.12.0

A patch-based distributed version control system, easy to use and fast.
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)
}