use serde::{Deserialize, Serialize}; /// The null OID representing "no object" in git protocol. pub const ZERO_OID: &str = "0000000000000000000000000000000000000000"; #[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct ObjectId(pub String); impl ObjectId { pub fn new(hex: impl AsRef) -> Self { Self(hex.as_ref().to_lowercase()) } pub fn as_str(&self) -> &str { &self.0 } } impl std::fmt::Display for ObjectId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } impl AsRef for ObjectId { fn as_ref(&self) -> &str { &self.0 } } pub fn hex_to_bytes(hex: &str) -> Result, crate::error::GitError> { let hex = hex.trim(); if !hex.len().is_multiple_of(2) { return Err(crate::error::GitError::InvalidOid( "hex oid has odd length".into(), )); } hex.as_bytes() .chunks_exact(2) .map(|pair| { let part = std::str::from_utf8(pair) .map_err(|e| crate::error::GitError::InvalidOid(e.to_string()))?; u8::from_str_radix(part, 16) .map_err(|e| crate::error::GitError::InvalidOid(e.to_string())) }) .collect() } impl TryFrom<&ObjectId> for gix::hash::ObjectId { type Error = crate::error::GitError; fn try_from(id: &ObjectId) -> Result { gix::hash::ObjectId::from_hex(id.as_str().as_bytes()) .map_err(|e| crate::error::GitError::InvalidOid(format!("invalid hex oid: {e}"))) } }