48b136a
//! object Use-case implementations for [`GitRepository`](crate::GitRepository).
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<ObjectFormat, crate::Error> {
if let Some(hit) = self
.cache
.get_sync::<ObjectFormat>(&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<bool, crate::Error> {
if let Some(hit) = self.cache_get_oid::<bool>("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<ObjectType, crate::Error> {
if let Some(hit) = self.cache_get_oid::<ObjectType>("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<u64, crate::Error> {
if let Some(hit) = self.cache_get_oid::<u64>("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<ObjectInfo, crate::Error> {
if let Some(hit) = self.cache_get_oid::<ObjectInfo>("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<WriteObjectResult, crate::Error> {
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 })
}
}