radicle-cob: Reference conversion from git2::Reference
It will be common for Reference to be converted from a `git2::Reference` when one is implementing `object::Storage`. Provide a `TryFrom` implementation between `git2::Reference` and `Reference`. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
6b303bdc97
commit
4112b0fdc5
|
|
@ -83,3 +83,49 @@ pub trait Storage {
|
|||
change: &Change,
|
||||
) -> Result<(), Self::UpdateError>;
|
||||
}
|
||||
|
||||
pub mod convert {
|
||||
use std::str;
|
||||
|
||||
use git_ref_format::RefString;
|
||||
use thiserror::Error;
|
||||
|
||||
use super::{Commit, Reference};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
#[error("the reference '{name}' does not point to a commit object")]
|
||||
NotCommit {
|
||||
name: RefString,
|
||||
#[source]
|
||||
err: git2::Error,
|
||||
},
|
||||
#[error(transparent)]
|
||||
Ref(#[from] git_ref_format::Error),
|
||||
#[error(transparent)]
|
||||
Utf8(#[from] str::Utf8Error),
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<git2::Reference<'a>> for Reference {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: git2::Reference<'a>) -> Result<Self, Self::Error> {
|
||||
let name = RefString::try_from(str::from_utf8(value.name_bytes())?)?;
|
||||
let target = Commit::from(value.peel_to_commit().map_err(|err| Error::NotCommit {
|
||||
name: name.clone(),
|
||||
err,
|
||||
})?);
|
||||
Ok(Self { name, target })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<git2::Commit<'a>> for Commit {
|
||||
fn from(commit: git2::Commit<'a>) -> Self {
|
||||
let parents = commit.parents().map(Commit::from).collect();
|
||||
Commit {
|
||||
id: commit.id().into(),
|
||||
parents,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
use std::{collections::HashMap, convert::TryFrom as _};
|
||||
|
||||
use git_ref_format::RefString;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::{
|
||||
change,
|
||||
object::{self, Commit, Reference},
|
||||
object::{self, Reference},
|
||||
ObjectId, Store,
|
||||
};
|
||||
|
||||
|
|
@ -14,6 +13,8 @@ use super::identity::{RemoteProject, Urn};
|
|||
pub mod error {
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::object::storage::convert;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Identity {
|
||||
#[error(transparent)]
|
||||
|
|
@ -28,6 +29,8 @@ pub mod error {
|
|||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Objects {
|
||||
#[error(transparent)]
|
||||
Conversion(#[from] convert::Error),
|
||||
#[error(transparent)]
|
||||
Git(#[from] git2::Error),
|
||||
#[error(transparent)]
|
||||
|
|
@ -122,12 +125,15 @@ impl object::Storage for Storage {
|
|||
);
|
||||
let local = {
|
||||
let r = self.raw.find_reference(&name)?;
|
||||
Some(resolve_reference(r)?)
|
||||
Some(Reference::try_from(r)?)
|
||||
};
|
||||
let remotes = self
|
||||
.raw
|
||||
.references_glob(&glob)?
|
||||
.map(|r| r.map_err(error::Objects::from).and_then(resolve_reference))
|
||||
.map(|r| {
|
||||
r.map_err(error::Objects::from)
|
||||
.and_then(|r| Reference::try_from(r).map_err(error::Objects::from))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(object::Objects { local, remotes })
|
||||
}
|
||||
|
|
@ -150,7 +156,7 @@ impl object::Storage for Storage {
|
|||
objects.insert(
|
||||
oid,
|
||||
object::Objects {
|
||||
local: Some(resolve_reference(r)?),
|
||||
local: Some(Reference::try_from(r)?),
|
||||
remotes: Vec::new(),
|
||||
},
|
||||
);
|
||||
|
|
@ -177,23 +183,3 @@ impl object::Storage for Storage {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_reference(r: git2::Reference) -> Result<Reference, error::Objects> {
|
||||
let commit = r.peel_to_commit()?;
|
||||
let target = resolve_parents(commit)?;
|
||||
Ok(Reference {
|
||||
name: RefString::try_from(r.name().unwrap().to_owned())?,
|
||||
target,
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_parents(commit: git2::Commit) -> Result<Commit, git2::Error> {
|
||||
let parents = commit
|
||||
.parents()
|
||||
.map(resolve_parents)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(Commit {
|
||||
id: commit.id().into(),
|
||||
parents,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue