diff --git a/radicle/src/cob.rs b/radicle/src/cob.rs index 7f5ff04f..b9d7db89 100644 --- a/radicle/src/cob.rs +++ b/radicle/src/cob.rs @@ -18,3 +18,48 @@ pub use radicle_cob::{ Store, TypeName, Update, Updated, Version, }; pub use radicle_cob::{create, get, git, list, remove, update}; + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct TypedId { + pub id: ObjectId, + pub type_name: TypeName, +} + +#[derive(Debug, thiserror::Error)] +pub enum ParseIdentifierError { + #[error(transparent)] + TypeName(#[from] TypeNameParse), + #[error(transparent)] + ObjectId(#[from] object::ParseObjectId), +} + +impl TypedId { + pub fn is_issue(&self) -> bool { + self.type_name == *issue::TYPENAME + } + + pub fn is_patch(&self) -> bool { + self.type_name == *patch::TYPENAME + } + + pub fn from_namespaced( + n: &crate::git::Namespaced, + ) -> Result, ParseIdentifierError> { + Self::from_qualified(&n.strip_namespace()) + } + + pub fn from_qualified(q: &crate::git::Qualified) -> Result, ParseIdentifierError> { + match q.non_empty_iter() { + ("refs", "cobs", type_name, mut id) => { + let Some(id) = id.next() else { + return Ok(None); + }; + Ok(Some(Self { + id: id.parse()?, + type_name: type_name.parse()?, + })) + } + _ => Ok(None), + } + } +}