114 lines · 3.6 KB · Rust
RawDownload
use bstr::{BStr, BString, ByteSlice};use git_hash::ObjectId;use std::{borrow::Cow, convert::TryFrom, fmt, path::Path}; /// Indicate that the given BString is a validate reference name or path that can be used as path on disk or written as target/// of a symbolic reference#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]pub struct FullName(pub(crate) BString); impl TryFrom<&str> for FullName {    type Error = git_validate::refname::Error;     fn try_from(value: &str) -> Result<Self, Self::Error> {        Ok(FullName(git_validate::refname(value.as_bytes().as_bstr())?.into()))    }} impl TryFrom<&BStr> for FullName {    type Error = git_validate::refname::Error;     fn try_from(value: &BStr) -> Result<Self, Self::Error> {        Ok(FullName(git_validate::refname(value)?.into()))    }} impl AsRef<BStr> for FullName {    fn as_ref(&self) -> &BStr {        self.0.as_bstr()    }} impl FullName {    /// Interpret this fully qualified reference name as partial name.    pub fn to_partial(&self) -> crate::PartialName<'_> {        crate::PartialName(self.0.as_bstr())    }     /// Interpret this fully qualified reference as shared full name    pub fn borrow(&self) -> crate::FullName<'_> {        crate::FullName(self.0.as_bstr())    }     /// Convert this name into the relative path, lossily, identifying the reference location relative to a repository    pub fn to_path(&self) -> Cow<'_, Path> {        self.0.to_path_lossy()    }     /// Dissolve this instance and return the buffer.    pub fn into_inner(self) -> BString {        self.0    }} /// Denotes a ref target, equivalent to [`Kind`][super::Kind], but with mutable data.#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]pub enum Target {    /// A ref that points to an object id    Peeled(ObjectId),    /// A ref that points to another reference by its validated name, adding a level of indirection.    ///    /// Note that this is an extension of gitoxide which will be helpful in logging all reference changes.    Symbolic(FullName),} impl Target {    /// Return true if this is a peeled target with a null hash    pub fn is_null(&self) -> bool {        match self {            Target::Peeled(oid) => oid.is_null(),            Target::Symbolic(_) => false,        }    }     /// Interpret this owned Target as shared Target    pub fn borrow(&self) -> crate::Target<'_> {        match self {            Target::Peeled(oid) => crate::Target::Peeled(&oid),            Target::Symbolic(name) => crate::Target::Symbolic(name.0.as_bstr()),        }    }     /// Create an instance that signals that a reference should exist if this value is used in a [`Change`][crate::transaction::Change].    pub fn must_exist() -> Self {        Target::Peeled(ObjectId::null_sha1())    }} impl<'a> From<crate::Target<'a>> for Target {    fn from(src: crate::Target<'a>) -> Self {        match src {            crate::Target::Peeled(oid) => Target::Peeled(oid.to_owned()),            crate::Target::Symbolic(name) => Target::Symbolic(FullName(name.to_owned())),        }    }} impl<'a> PartialEq<crate::Target<'a>> for Target {    fn eq(&self, other: &crate::Target<'a>) -> bool {        match (self, other) {            (Target::Peeled(lhs), crate::Target::Peeled(rhs)) => lhs == rhs,            (Target::Symbolic(lhs), crate::Target::Symbolic(rhs)) => lhs.as_ref() == *rhs,            _ => false,        }    }} impl fmt::Display for Target {    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {        match self {            Target::Peeled(oid) => oid.fmt(f),            Target::Symbolic(name) => write!(f, "ref: {}", name.as_ref()),        }    }}