wof 1.0.0

The Who's On First rust library and command line.
Documentation
use crate::utils::ResultExit;
use git2::{DiffFormat, DiffLine, ObjectType, Repository};
use std::path::PathBuf;
use std::vec::Vec;

pub struct Git {
  workdir: PathBuf,
}

impl Git {
  pub fn new() -> Git {
    return Git {
      workdir: Repository::discover(".")
        .expect_exit("This is not a git repository. Make sure to be in a git folder")
        .workdir()
        .expect("Git working directory not found. Should not happen.")
        .to_path_buf(),
    };
  }

  pub fn repository(&self) -> Repository {
    Repository::discover(self.workdir.as_path())
      .expect("This is not a git repository. Should not happen.")
  }

  pub fn get_changes_from_commit(&self, commit: &String) -> Vec<PathBuf> {
    let repo = self.repository();
    let obj_dst = repo
      .revparse_single(commit.as_str())
      .expect_exit(format!("Commit/branch {} not found", commit).as_str());
    let obj_src = obj_dst
      .peel_to_commit()
      .expect("Can't convert the object to a commit. Should not happen.")
      .parent(0)
      .expect_exit(format!("Can't the parent object of {}", commit).as_str());

    let tree_src = obj_src.tree().expect("Can't get the source tree.");
    let tree_dst = obj_dst
      .peel(ObjectType::Tree)
      .expect("Can't get the destination tree.");
    let mut paths: Vec<PathBuf> = Vec::new();
    repo
      .diff_tree_to_tree(Some(&tree_src), tree_dst.as_tree(), None)
      .expect("Can't create the diff between source and destination")
      .print(DiffFormat::NameOnly, |_delta, _hunk, line| {
        paths.push(self.diff_line_to_real_path(line));
        true
      })
      .expect_exit("Can't create the diff for this commit");
    paths
  }

  pub fn get_changes_from_stagged(&self) -> Vec<PathBuf> {
    let mut paths: Vec<PathBuf> = Vec::new();
    let repo = self.repository();
    let tree = repo
      .revparse_single("HEAD")
      .expect_exit("HEAD not found in your git tree")
      .peel(ObjectType::Tree)
      .expect("Can't get the HEAD tree.");

    repo
      .diff_tree_to_index(tree.as_tree(), None, None)
      .expect("Can't create the diff for stagged elements")
      .print(DiffFormat::NameOnly, |_delta, _hunk, line| {
        paths.push(self.diff_line_to_real_path(line));
        true
      })
      .expect_exit("Can't create the stagged diff");
    paths
  }

  fn diff_line_to_real_path(&self, line: DiffLine) -> PathBuf {
    self.workdir.as_path().join(
      std::str::from_utf8(line.content())
        .expect("WOF Elements should be utf-8.")
        .trim(),
    )
  }
}