Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add TypeName & ObjectId parser
Fintan Halpenny committed 3 years ago
commit a985e067a51a9042282c6129a97375e5ecaaf7cc
parent b4bc032113ac663575f45c24421804b60737da7e
4 files changed +45 -17
modified radicle-cob/src/object.rs
@@ -11,7 +11,9 @@ use serde::{Deserialize, Serialize};
use thiserror::Error;

pub mod collaboration;
-
pub use collaboration::{create, get, info, list, update, CollaborativeObject, Create, Update};
+
pub use collaboration::{
+
    create, get, info, list, parse_refstr, update, CollaborativeObject, Create, Update,
+
};

pub mod storage;
pub use storage::{Commit, Objects, Reference, Storage};
@@ -30,7 +32,7 @@ impl FromStr for ObjectId {
    type Err = ParseObjectId;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
-
        let oid = Oid::try_from(s.as_bytes())?;
+
        let oid = Oid::from_str(s)?;
        Ok(ObjectId(oid))
    }
}
modified radicle-cob/src/object/collaboration.rs
@@ -53,3 +53,43 @@ impl CollaborativeObject {
        self.history.tips().into_iter().map(Oid::from).collect()
    }
}
+

+
/// Takes a `refname` and performs a best attempt to extract out the
+
/// [`TypeName`] and [`ObjectId`] from it.
+
///
+
/// This assumes that the `refname` is in a
+
/// [`git_ref_format::Qualified`] format. If it has any
+
/// `refs/namespaces`, they will be stripped to access the underlying
+
/// [`git_ref_format::Qualified`] format.
+
///
+
/// In the [`git_ref_format::Qualified`] format it assumes that the
+
/// reference name is of the form:
+
///
+
///   `refs/<category>/<typename>/<object_id>[/<rest>*]`
+
///
+
/// Note that their may be more components to the path after the
+
/// [`ObjectId`] but they are ignored.
+
///
+
/// Also note that this will return `None` if:
+
///
+
///   * The `refname` is not [`git_ref_format::Qualified`]
+
///   * The parsing of the [`ObjectId`] fails
+
///   * The parsing of the [`TypeName`] fails
+
pub fn parse_refstr<R>(name: &R) -> Option<(TypeName, ObjectId)>
+
where
+
    R: AsRef<git_ref_format::RefStr>,
+
{
+
    use git_ref_format::Qualified;
+
    let name = name.as_ref();
+
    let refs_cobs = match name.to_namespaced() {
+
        None => Qualified::from_refstr(name)?,
+
        Some(ns) => ns.strip_namespace_recursive(),
+
    };
+

+
    let (_refs, _cobs, typename, mut object_id) = refs_cobs.non_empty_components();
+
    let object = object_id
+
        .next()
+
        .and_then(|oid| oid.parse::<ObjectId>().ok())?;
+
    let name = typename.parse::<TypeName>().ok()?;
+
    Some((name, object))
+
}
modified radicle/src/git.rs
@@ -141,20 +141,6 @@ pub mod refs {
                .join(Component::from(typename))
                .join(Component::from(object_id))
        }
-

-
        pub fn cob_suffix<R>(cob: &R) -> Option<(cob::TypeName, cob::ObjectId)>
-
        where
-
            R: AsRef<RefStr>,
-
        {
-
            let cob = cob.as_ref().to_namespaced()?;
-
            let cob = cob.strip_namespace();
-
            let (_refs, _cobs, typename, mut object_id) = cob.non_empty_components();
-
            let object_id = object_id
-
                .next()
-
                .and_then(|oid| oid.parse::<git2::Oid>().ok())?;
-
            let typename = typename.parse::<cob::TypeName>().ok()?;
-
            Some((typename, object_id.into()))
-
        }
    }

    pub mod workdir {
modified radicle/src/storage/git.rs
@@ -736,7 +736,7 @@ impl cob::object::Storage for Repository {
            let reference = reference.ok()?;
            match RefStr::try_from_str(reference.name()?) {
                Ok(name) => {
-
                    let (ty, object_id) = git::refs::storage::cob_suffix(&name)?;
+
                    let (ty, object_id) = cob::object::parse_refstr(&name)?;
                    if ty == *typename {
                        Some(
                            cob::object::Reference::try_from(reference)