Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle-cob: Reference conversion from git2::Reference
Fintan Halpenny committed 3 years ago
commit 4112b0fdc505d9a7e9cf24b1afa10fc2fba330e1
parent 6b303bdc97ee3749413885fc6c49ca9a6e14becf
2 files changed +57 -25
modified radicle-cob/src/object/storage.rs
@@ -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,
+
            }
+
        }
+
    }
+
}
modified radicle-cob/src/test/storage.rs
@@ -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)]
@@ -29,6 +30,8 @@ pub mod error {
    #[derive(Debug, Error)]
    pub enum Objects {
        #[error(transparent)]
+
        Conversion(#[from] convert::Error),
+
        #[error(transparent)]
        Git(#[from] git2::Error),
        #[error(transparent)]
        Format(#[from] git_ref_format::Error),
@@ -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,
-
    })
-
}