summaryrefslogtreecommitdiff
path: root/src/object.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/object.rs')
-rw-r--r--src/object.rs48
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