use std::fmt::Display;
use crate::{
errors::GitError,
hash::ObjectHash,
internal::object::{ObjectTrait, types::ObjectType},
};
#[derive(Eq, Debug, Clone)]
pub struct Blob {
pub id: ObjectHash,
pub data: Vec<u8>,
}
impl PartialEq for Blob {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Display for Blob {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
writeln!(f, "Type: Blob").unwrap();
writeln!(f, "Size: {}", self.data.len())
}
}
impl ObjectTrait for Blob {
fn from_bytes(data: &[u8], hash: ObjectHash) -> Result<Self, GitError>
where
Self: Sized,
{
Ok(Blob {
id: hash,
data: data.to_vec(),
})
}
fn get_type(&self) -> ObjectType {
ObjectType::Blob
}
fn get_size(&self) -> usize {
self.data.len()
}
fn to_data(&self) -> Result<Vec<u8>, GitError> {
Ok(self.data.clone())
}
}
impl Blob {
pub fn from_content(content: &str) -> Self {
let content = content.as_bytes().to_vec();
Blob::from_content_bytes(content)
}
pub fn from_content_bytes(content: Vec<u8>) -> Self {
Blob {
id: ObjectHash::from_type_and_data(ObjectType::Blob, &content),
data: content,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
hash::{HashKind, set_hash_kind_for_test},
internal::object::ObjectTrait,
};
#[test]
fn test_blob_from_content() {
let _guard = set_hash_kind_for_test(HashKind::Sha1);
let content = "Hello, world!";
let blob = Blob::from_content(content);
assert_eq!(
blob.id.to_string(),
"5dd01c177f5d7d1be5346a5bc18a569a7410c2ef"
);
let hash_from_trait = blob.object_hash().unwrap();
assert_eq!(hash_from_trait.to_string(), blob.id.to_string());
}
#[test]
fn test_blob_from_content_sha256() {
let _guard = set_hash_kind_for_test(HashKind::Sha256);
let content = "Hello, world!";
let blob = Blob::from_content(content);
assert_eq!(
blob.id.to_string(),
"178b5fbed164aee269fee7323badf7269cca0eed0875717b0d2d4f9819164c3f"
);
}
}