diff --git a/radicle-surf/src/blob.rs b/radicle-surf/src/blob.rs index 2a9ba83..2326e74 100644 --- a/radicle-surf/src/blob.rs +++ b/radicle-surf/src/blob.rs @@ -95,7 +95,13 @@ impl<'a> Blob> { /// Represents a blob with borrowed content bytes. pub struct BlobRef<'a> { - inner: git2::Blob<'a>, + pub(crate) inner: git2::Blob<'a>, +} + +impl<'a> BlobRef<'a> { + pub fn id(&self) -> Oid { + self.inner.id().into() + } } impl AsRef<[u8]> for BlobRef<'_> { @@ -138,3 +144,26 @@ where state.end() } } + +#[cfg(feature = "serde")] +impl<'a> Serialize for BlobRef<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + const FIELDS: usize = 3; + let mut state = serializer.serialize_struct("BlobRef", FIELDS)?; + state.serialize_field("id", &self.id())?; + state.serialize_field("binary", &self.inner.is_binary())?; + + let bytes = self.as_ref(); + match std::str::from_utf8(bytes) { + Ok(s) => state.serialize_field("content", s)?, + Err(_) => { + let encoded = base64::encode(bytes); + state.serialize_field("content", &encoded)? + }, + }; + state.end() + } +} diff --git a/radicle-surf/src/repo.rs b/radicle-surf/src/repo.rs index 9d75350..7d98f6f 100644 --- a/radicle-surf/src/repo.rs +++ b/radicle-surf/src/repo.rs @@ -301,6 +301,12 @@ impl Repository { Ok(Blob::>::new(file.id(), git2_blob, last_commit)) } + pub fn blob_ref(&self, oid: Oid) -> Result, Error> { + Ok(BlobRef { + inner: self.find_blob(oid)?, + }) + } + /// Returns the last commit, if exists, for a `path` in the history of /// `rev`. pub fn last_commit(&self, path: &P, rev: C) -> Result, Error>