use crate::branch::Branch;
use git2::{self, Oid};
use std::{fmt, sync::Arc};
pub type GitResult<T> = Result<T, GitError>;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct HashId(String);
impl fmt::Display for HashId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl HashId {
pub fn to_oid(&self) -> Oid {
self.clone().into()
}
pub fn to_string(&self) -> String {
self.0.clone()
}
}
impl From<Oid> for HashId {
fn from(o: Oid) -> Self {
Self(o.to_string())
}
}
impl From<HashId> for Oid {
fn from(hid: HashId) -> Self {
Oid::from_str(hid.0.as_str()).expect(&format!(
"Tried turning an invalid HashId variant into an Oid: {:?}",
hid
))
}
}
impl<'any> From<&'any HashId> for Oid {
fn from(hid: &'any HashId) -> Self {
Oid::from_str(hid.0.as_str()).expect(&format!(
"Tried turning an invalid HashId variant into an Oid: {:?}",
hid
))
}
}
#[derive(Debug)]
pub enum GitError {
AllBad,
}
impl From<git2::Error> for GitError {
fn from(_: git2::Error) -> Self {
Self::AllBad
}
}
#[derive(Clone)]
pub struct Repository {
inner: Arc<git2::Repository>,
}
impl Repository {
pub fn open(path: &str) -> GitResult<Self> {
Ok(Self {
inner: Arc::new(git2::Repository::open(path)?),
})
}
pub fn branches(&self) -> GitResult<Vec<Branch>> {
Ok(self
.inner
.branches(None)?
.into_iter()
.filter_map(|e| e.ok())
.map(|(branch, _)| {
let name = branch.name().unwrap().unwrap().into();
let head = branch.get().peel_to_commit().unwrap().id().into();
Branch::new(&self.inner, name, head)
})
.collect())
}
pub fn branch(&self, name: String) -> Option<Branch> {
self.branches().ok().and_then(|ok| {
ok.into_iter()
.filter(|b| b.name().is_some())
.find(|b| &b.name().unwrap() == &name)
})
}
}