use gix::hash::ObjectId; use crate::GitRepository; use crate::object::impls::ObjectOps; use crate::object::types::{ObjectFormat, ObjectInfo, ObjectType, WriteObjectResult}; use crate::validate; impl ObjectOps for GitRepository { fn object_format(&self) -> Result { if let Some(hit) = self .cache .get_sync::(&format!("object_format.{}", self.path.display())) { return Ok(hit); } let repo = self.repo()?; let v: ObjectFormat = repo.object_hash().into(); self.cache.set_sync_with_ttl( &format!("object_format.{}", self.path.display()), v, crate::usecase_cache::IMMUTABLE_TTL, ); Ok(v) } fn object_exists(&self, id: &ObjectId) -> Result { if let Some(hit) = self.cache_get_oid::("exists", id) { return Ok(hit); } let repo = self.repo()?; let v = repo .try_find_object(*id) .map(|o| o.is_some()) .map_err(|e| crate::Error::Find(e.to_string()))?; self.cache_put_oid("exists", id, &v); Ok(v) } fn object_type_of(&self, id: &ObjectId) -> Result { if let Some(hit) = self.cache_get_oid::("type", id) { return Ok(hit); } let repo = self.repo()?; let obj = repo .find_object(*id) .map_err(|e| crate::Error::Find(e.to_string()))?; let v: ObjectType = obj.kind.into(); self.cache_put_oid("type", id, &v); Ok(v) } fn object_size_of(&self, id: &ObjectId) -> Result { if let Some(hit) = self.cache_get_oid::("size", id) { return Ok(hit); } let repo = self.repo()?; let obj = repo .find_object(*id) .map_err(|e| crate::Error::Find(e.to_string()))?; let v = obj.data.len() as u64; self.cache_put_oid("size", id, &v); Ok(v) } fn object_info(&self, id: &ObjectId) -> Result { if let Some(hit) = self.cache_get_oid::("info", id) { return Ok(hit); } let repo = self.repo()?; let obj = repo .find_object(*id) .map_err(|e| crate::Error::Find(e.to_string()))?; let v = ObjectInfo { id: obj.id, object_type: obj.kind.into(), size: obj.data.len() as u64, }; self.cache_put_oid("info", id, &v); Ok(v) } fn object_write_object( &self, kind: ObjectType, data: &[u8], ) -> Result { validate::enforce_max_size(data, validate::MAX_OBJECT_SIZE, "object")?; let repo = self.repo()?; let gix_kind = match kind { ObjectType::Blob => gix::objs::Kind::Blob, ObjectType::Tree => gix::objs::Kind::Tree, ObjectType::Commit => gix::objs::Kind::Commit, ObjectType::Tag => gix::objs::Kind::Tag, }; let id = gix::objs::Write::write_buf(&repo, gix_kind, data) .map_err(|e| crate::Error::Odb(e.to_string()))?; tracing::info!(object = ?id, kind = ?gix_kind, size = data.len(), "object written"); Ok(WriteObjectResult { id }) } }