pub fn write_index(items: Vec<IndexFile>) -> io::Result<()> {
    // https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html#method.truncate

    // Might want to create and replace the index file instead of overwriting it in case of errors
    let mut file = OpenOptions::new()
        .write(true)
        .truncate(true)
        .open(INDEX_PATH)
        .expect("Could not open index file");

    // Write magic number and version
    file.write_all(&[0x44, 0x49, 0x52, 0x43, 0x0, 0x0, 0x0, 0x02])?;

    let num_file = items.len() as u32;

    // Write number of files as 4 byte number
    file.write_all(&num_file.to_be_bytes())?;

    for item in items.iter() {
        // Write 6 32-bit (4-byte) info fields
        // ctime seconds, ctime nanosecond fractions, mtime seconds, mtime nanosecond fractions, dev (null on windows), ino (null on windows)
        file.write_all(&item.ctime.to_be_bytes())?;
        file.write_all(&item.ctime_fractions.to_be_bytes())?;
        file.write_all(&item.mtime.to_be_bytes())?;
        file.write_all(&item.mtime_fractions.to_be_bytes())?;
        match item.dev {
            Some(x) => file.write_all(&x.to_be_bytes())?,
            None => file.write_all(&[0, 0, 0, 0])?,
        };
        match item.ino {
            Some(x) => file.write_all(&x.to_be_bytes())?,
            None => file.write_all(&[0, 0, 0, 0])?,
        };

        // Write out mode
        // 4-bits: object type (regular (1000), symlink(1010), gitlink(1110))
        // 3-bits: unused
        // 9-bit: permissions (755 or 644)
        // assume regular file for now
        file.write_all(&[0b1000_0001])?;

        if item.permissions == "644" {
            file.write_all(&[0b1010_0100])?;
        } else {
            file.write_all(&[0b1110_1101])?;
        }

        // Write 3 4-byte info fields
        // uid (null on windows), guid (null on windows), file size
        match item.uid {
            Some(x) => file.write_all(&x.to_be_bytes())?,
            None => file.write_all(&[0, 0, 0, 0])?,
        };
        match item.gid {
            Some(x) => file.write_all(&x.to_be_bytes())?,
            None => file.write_all(&[0, 0, 0, 0])?,
        };
        file.write_all(&item.size.to_be_bytes())?;

        file.write_all(&hash_to_vec(&item.object_hash))?;

        let filename_length = item.filename.len();
        debug_assert!(filename_length <= 255);

        // write flag bytes
        // 1 bit assume valid
        // 1 bit extended (must be 0 in version 2)
        // 2 bit stage (during merge)
        // 12 bit name length if the length is less than 0xFF; otherwise 0xFF
        file.write_all(&[0b1000_0000, (filename_length as u8)])?;

        file.write_all(item.filename.as_bytes())?;

        // Write at least one NUL byte (and up to 8),
        // The filename ends with a NUL-terminator, and is padded to the nearest multiple of 8 bytes (for the entry)
        let bytes_written = 60; // bytes written for an entry
        let total_bytes = bytes_written + filename_length;
        let padding = 8 - (total_bytes % 8);
        let nul_buf = vec![0; padding as usize];
        file.write_all(&nul_buf)?;
    }

    Ok(())
}
/// Writes the given index structs back to the index file
Writes the given index structs back to the index file
Writes the given index structs back to the index file
pub fn write_index(items: Vec<IndexFile>) -> io::Result<()> {
    // https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html#method.truncate
    // Might want to create and replace the index file instead of overwriting it in case of errors
    let mut file = OpenOptions::new()
        .write(true)
        .truncate(true)
        .open(INDEX_PATH)
        .expect("Could not open index file");
    // Write magic number and version
    file.write_all(&[0x44, 0x49, 0x52, 0x43, 0x0, 0x0, 0x0, 0x02])?;
    let num_file = items.len() as u32;
    // Write number of files as 4 byte number
    file.write_all(&num_file.to_be_bytes())?;
    for item in items.iter() {
        // Write 6 32-bit (4-byte) info fields
        // ctime seconds, ctime nanosecond fractions, mtime seconds, mtime nanosecond fractions, dev (null on windows), ino (null on windows)
        file.write_all(&item.ctime.to_be_bytes())?;
        file.write_all(&item.ctime_fractions.to_be_bytes())?;
        file.write_all(&item.mtime.to_be_bytes())?;
        file.write_all(&item.mtime_fractions.to_be_bytes())?;
        match item.dev {
            Some(x) => file.write_all(&x.to_be_bytes())?,
            None => file.write_all(&[0, 0, 0, 0])?,
        };
        match item.ino {
            Some(x) => file.write_all(&x.to_be_bytes())?,
            None => file.write_all(&[0, 0, 0, 0])?,
        };
        // Write out mode
        // 4-bits: object type (regular (1000), symlink(1010), gitlink(1110))
        // 3-bits: unused
        // 9-bit: permissions (755 or 644)
        // assume regular file for now
        file.write_all(&[0b1000_0001])?;
        if item.permissions == "644" {
            file.write_all(&[0b1010_0100])?;
        } else {
            file.write_all(&[0b1110_1101])?;
        }
        // Write 3 4-byte info fields
        // uid (null on windows), guid (null on windows), file size
        match item.uid {
            Some(x) => file.write_all(&x.to_be_bytes())?,
            None => file.write_all(&[0, 0, 0, 0])?,
        };
        match item.gid {
            Some(x) => file.write_all(&x.to_be_bytes())?,
            None => file.write_all(&[0, 0, 0, 0])?,
        };
        file.write_all(&item.size.to_be_bytes())?;
        file.write_all(&hash_to_vec(&item.object_hash))?;
        let filename_length = item.filename.len();
        debug_assert!(filename_length <= 255);
        // write flag bytes
        // 1 bit assume valid
        // 1 bit extended (must be 0 in version 2)
        // 2 bit stage (during merge)
        // 12 bit name length if the length is less than 0xFF; otherwise 0xFF
        file.write_all(&[0b1000_0000, (filename_length as u8)])?;
        file.write_all(item.filename.as_bytes())?;
        // Write at least one NUL byte (and up to 8),
        // The filename ends with a NUL-terminator, and is padded to the nearest multiple of 8 bytes (for the entry)
        let bytes_written = 60; // bytes written for an entry
        let total_bytes = bytes_written + filename_length;
        let padding = 8 - (total_bytes % 8);
        let nul_buf = vec![0; padding as usize];
        file.write_all(&nul_buf)?;
    }
    Ok(())
}
pub fn write_index ( items : Vec < IndexFile > ) -> io :: Result < ( ) > { // https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html#method.truncate // Might want to create and replace the index file instead of overwriting it in case of errors let mut file = OpenOptions :: new ( ) . write ( true ) . truncate ( true ) . open ( INDEX_PATH ) . expect ( " " ) ; // Write magic number and version file . write_all ( & [ 0x44 , 0x49 , 0x52 , 0x43 , 0x0 , 0x0 , 0x0 , 0x02 ] ) ? ; let num_file = items . len ( ) as u32 ; // Write number of files as 4 byte number file . write_all ( & num_file . to_be_bytes ( ) ) ? ; for item in items . iter ( ) { // Write 6 32-bit (4-byte) info fields // ctime seconds, ctime nanosecond fractions, mtime seconds, mtime nanosecond fractions, dev (null on windows), ino (null on windows) file . write_all ( & item . ctime . to_be_bytes ( ) ) ? ; file . write_all ( & item . ctime_fractions . to_be_bytes ( ) ) ? ; file . write_all ( & item . mtime . to_be_bytes ( ) ) ? ; file . write_all ( & item . mtime_fractions . to_be_bytes ( ) ) ? ; match item . dev { Some ( x ) => file . write_all ( & x . to_be_bytes ( ) ) ? , None => file . write_all ( & [ 0 , 0 , 0 , 0 ] ) ? , } ; match item . ino { Some ( x ) => file . write_all ( & x . to_be_bytes ( ) ) ? , None => file . write_all ( & [ 0 , 0 , 0 , 0 ] ) ? , } ; // Write out mode // 4-bits: object type (regular (1000), symlink(1010), gitlink(1110)) // 3-bits: unused // 9-bit: permissions (755 or 644) // assume regular file for now file . write_all ( & [ 0b1000_0001 ] ) ? ; if item . permissions == " " { file . write_all ( & [ 0b1010_0100 ] ) ? ; } else { file . write_all ( & [ 0b1110_1101 ] ) ? ; } // Write 3 4-byte info fields // uid (null on windows), guid (null on windows), file size match item . uid { Some ( x ) => file . write_all ( & x . to_be_bytes ( ) ) ? , None => file . write_all ( & [ 0 , 0 , 0 , 0 ] ) ? , } ; match item . gid { Some ( x ) => file . write_all ( & x . to_be_bytes ( ) ) ? , None => file . write_all ( & [ 0 , 0 , 0 , 0 ] ) ? , } ; file . write_all ( & item . size . to_be_bytes ( ) ) ? ; file . write_all ( & hash_to_vec ( & item . object_hash ) ) ? ; let filename_length = item . filename . len ( ) ; debug_assert ! ( filename_length 255 ) ; // write flag bytes // 1 bit assume valid // 1 bit extended (must be 0 in version 2) // 2 bit stage (during merge) // 12 bit name length if the length is less than 0xFF; otherwise 0xFF file . write_all ( & [ 0b1000_0000 , ( filename_length as u8 ) ] ) ? ; file . write_all ( item . filename . as_bytes ( ) ) ? ; // Write at least one NUL byte (and up to 8), // The filename ends with a NUL-terminator, and is padded to the nearest multiple of 8 bytes (for the entry) let bytes_written = 60 ; // bytes written for an entry let total_bytes = bytes_written + filename_length ; let padding = 8 - ( total_bytes % 8 ) ; let nul_buf = vec ! [ 0 padding as usize ] ; file . write_all ( & nul_buf ) ? ; } Ok ( ( ) ) }
Writes the given index structs back to the index file
Writes the given index structs back to the index file
items
Vec<IndexFile>
items
Vec<IndexFile>