diff options
-rw-r--r-- | Cargo.lock | 78 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/object.rs | 48 |
3 files changed, 122 insertions, 5 deletions
@@ -59,6 +59,15 @@ dependencies = [ ] [[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -123,6 +132,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" [[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] name = "crc32fast" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -132,6 +150,26 @@ dependencies = [ ] [[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] name = "flate2" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -142,6 +180,16 @@ dependencies = [ ] [[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] name = "grit" version = "0.1.0" dependencies = [ @@ -149,6 +197,7 @@ dependencies = [ "configparser 3.1.0", "flate2", "ini", + "sha1", ] [[package]] @@ -173,6 +222,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] name = "miniz_oxide" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -206,6 +261,17 @@ dependencies = [ ] [[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -223,6 +289,12 @@ dependencies = [ ] [[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -235,6 +307,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -9,3 +9,4 @@ clap = { version = "4.5.32", features = ["derive"] } configparser = "3.1.0" flate2 = "1.1.0" ini = "1.3.0" +sha1 = "0.10.6" 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 |