diff options
-rw-r--r-- | Cargo.lock | 41 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/object.rs | 81 | ||||
-rw-r--r-- | src/utilities.rs | 16 |
4 files changed, 134 insertions, 5 deletions
@@ -3,6 +3,12 @@ version = 4 [[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] name = "anstream" version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -53,6 +59,12 @@ dependencies = [ ] [[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] name = "clap" version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -111,11 +123,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" [[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "flate2" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] name = "grit" version = "0.1.0" dependencies = [ "clap", "configparser 3.1.0", + "flate2", "ini", ] @@ -141,6 +173,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + +[[package]] name = "once_cell" version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7,4 +7,5 @@ description = "Brainrot git" [dependencies] clap = { version = "4.5.32", features = ["derive"] } configparser = "3.1.0" +flate2 = "1.1.0" ini = "1.3.0" diff --git a/src/object.rs b/src/object.rs index 6374911..5824c47 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,12 +1,91 @@ -enum GitObjectType { +use std::fs::File; +use std::io::{BufReader, Read}; +use std::path::PathBuf; +use flate2::read::ZlibDecoder; +use crate::die; + +pub enum GitObjectType { Blob, Commit, Tag, Tree, + Undefined, } struct GitObject { object_type: GitObjectType, size: usize, data: Vec<u8>, +} + +impl GitObject { + fn new() -> Self { + Self { + object_type: GitObjectType::Undefined, + size: 0, + data: Vec::new(), + } + } + + fn from_file(path: PathBuf) -> Self { + if !path.is_file() { + return Self::new(); + } + if let Ok(compressed_content) = File::open(path.clone()) { + let sha = path.file_name().unwrap().to_str().unwrap(); + let decoder = ZlibDecoder::new(BufReader::new(compressed_content)); + let mut reader = ZlibDecoder::new(decoder); + + let mut type_buffer = Vec::new(); + let mut size_buffer = Vec::new(); + let mut data = Vec::new(); + let mut byte = [0u8; 1]; + + let mut current_segment: u8 = 0; // 0: type, 1: size, 2: content + while reader.read_exact(&mut byte).is_ok() { + match current_segment { + 0 => { + if byte[0] != b' ' { + type_buffer.push(byte[0]); + } else { + current_segment += 1; + } + } + 1 => { + if byte[0] == b'\x00' { + size_buffer.push(byte[0]); + } else { + current_segment += 1; + } + } + _ => { + data.push(byte[0]); + } + } + } + let object_type = match String::from_utf8_lossy(&type_buffer).to_string().as_str() { + "commit" => { GitObjectType::Commit } + "tree" => { GitObjectType::Tree } + "tag" => { GitObjectType::Tag } + "blob" => { GitObjectType::Blob } + _ => { + die!( + "Unknown object type: {} in object {}", + String::from_utf8_lossy(&type_buffer), + sha + ); + } + }; + let Ok(size) = String::from_utf8_lossy(&size_buffer).to_string().parse::<usize>() else { + die!("Malformed object {}, unknown size", sha); + }; + Self { + object_type, + size, + data, + } + } else { + Self::new() + } + } }
\ No newline at end of file diff --git a/src/utilities.rs b/src/utilities.rs index bc78495..2c7a43f 100644 --- a/src/utilities.rs +++ b/src/utilities.rs @@ -5,10 +5,18 @@ pub type ConfigHashMap = HashMap<String, HashMap<String, Option<String>>>; #[macro_export] macro_rules! die { - ($message:expr) => { - println!("{}", $message); - std::process::exit(1); - } + ($msg:expr) => { + { + println!("{}", $msg); + std::process::exit(1); + } + }; + ($fmt:expr, $($args:tt)*) => { + { + println!($fmt, $($args)*); + std::process::exit(1); + } + }; } #[macro_export] |