diff options
author | Rosyid Haryadi <rosyid_haryadi@protonmail.com> | 2025-03-17 01:54:33 +0700 |
---|---|---|
committer | Rosyid Haryadi <rosyid_haryadi@protonmail.com> | 2025-03-17 01:54:33 +0700 |
commit | 2d79ca4bb935bd5b042812ff2018b90420de2eb8 (patch) | |
tree | 00de8bc058d967e34c04fd06b4aa2e8493487739 /src | |
parent | c8a05cdfc35604edddb54c9c36506742abdeadeb (diff) |
upd: write object struct to file
Diffstat (limited to 'src')
-rw-r--r-- | src/object.rs | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/src/object.rs b/src/object.rs index b270fb9..ae65258 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,8 +1,11 @@ -use crate::die; -use flate2::read::ZlibDecoder; +use std::fs; +use crate::{create_path_or_die, die}; +use flate2::read::{ZlibDecoder, ZlibEncoder}; use std::fs::File; -use std::io::Read; +use std::io::{BufReader, Read, Write}; use std::path::PathBuf; +use flate2::Compression; +use sha1::{Digest, Sha1}; pub enum GitObjectType { Blob, @@ -52,10 +55,10 @@ impl GitObject { let data: Vec<u8> = iter.cloned().collect(); let object_type = match String::from_utf8_lossy(&type_buffer).to_string().as_str() { + "blob" => { GitObjectType::Blob } "commit" => { GitObjectType::Commit } - "tree" => { GitObjectType::Tree } "tag" => { GitObjectType::Tag } - "blob" => { GitObjectType::Blob } + "tree" => { GitObjectType::Tree } _ => { die!("Unknown type in object {}", sha); } @@ -75,4 +78,39 @@ impl GitObject { Self::new() } } + + pub fn write_to_file(&mut self, git_object_dir: PathBuf) { + let object_type = match self.object_type { + GitObjectType::Blob => { "blob " } + GitObjectType::Commit => { "commit " } + GitObjectType::Tag => { "tag " } + GitObjectType::Tree => { "tree " } + _ => { die!("Cannot write to object file, type unknown") } + }; + let mut bytes_to_write = Vec::from(object_type); + let mut size_in_bytes = Vec::from(self.size.to_string()); + bytes_to_write.append(&mut size_in_bytes); + bytes_to_write.push(0); + bytes_to_write.append(&mut self.data); + + let mut hasher = Sha1::new(); + hasher.update(&bytes_to_write); + let hash = hasher.finalize(); + let sha = hash.iter() + .map(|byte| format!("{:02x}", byte)) + .collect::<String>(); + + let buff = BufReader::new(bytes_to_write.as_slice()); + let mut encoder = ZlibEncoder::new(buff, Compression::fast()); + let mut compressed = Vec::new(); + encoder.read_to_end(&mut compressed).unwrap(); + + let object_dir = git_object_dir.join(&sha[..2]); + create_path_or_die!(dir: object_dir.clone(), "Failed to create object file, could not create directory"); + let mut file = fs::OpenOptions::new() + .create(true) + .write(true) + .open(object_dir.join(&sha[2..])).unwrap(); + file.write_all(compressed.as_slice()).unwrap(); + } }
\ No newline at end of file |