summaryrefslogtreecommitdiff
path: root/src/object.rs
diff options
context:
space:
mode:
authorRosyid Haryadi <rosyid_haryadi@protonmail.com>2025-03-16 15:45:43 +0700
committerRosyid Haryadi <rosyid_haryadi@protonmail.com>2025-03-16 15:45:43 +0700
commit78fdb766da10fd5d9ffe803e02b18369efea1cbd (patch)
tree9cbe233b18b97a777062e745634a20bff746e8c4 /src/object.rs
parent3e8903a54667f24dd8e7f1b74d97ee772c032e64 (diff)
upd: git object. [not tested yet]
Diffstat (limited to 'src/object.rs')
-rw-r--r--src/object.rs81
1 files changed, 80 insertions, 1 deletions
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