thin-fetch 0.1.0

Low-level Git crate to fetch objects with high granularity
Documentation
//! Git objects.

use std::io::Write;

use gix_object::{Kind, WriteTo};

use ring::digest::Digest;

mod blob;
mod commit;
mod tag;
mod tree;

pub use blob::Blob;
pub use commit::Commit;
pub use tag::Tag;
pub use tree::{Tree, TreeEntry};

use crate::{Error, WithError};

#[derive(Debug)]
pub enum Object {
    Commit(Box<Commit>),
    Tree(Tree),
    Blob(Blob),
    Tag(Tag),
}

impl Object {
    #[must_use]
    pub fn hash(&self) -> Digest {
        match self {
            Self::Commit(data) => data.hash,
            Self::Tree(tree) => tree.hash,
            Self::Blob(blob) => blob.hash,
            Self::Tag(tag) => tag.hash,
        }
    }

    #[must_use]
    pub fn kind(&self) -> Kind {
        match self {
            Self::Commit(_) => Kind::Commit,
            Self::Tree(_) => Kind::Tree,
            Self::Blob(_) => Kind::Blob,
            Self::Tag(_) => Kind::Tag,
        }
    }

    /// # Errors
    pub fn write_to<W: Write>(&self, mut writer: W) -> Result<(), Error> {
        match self {
            Object::Commit(commit) => {
                let size = commit.size();
                write!(writer, "commit {size}\x00")?;

                commit
                    .commit
                    .write_to(&mut writer)
                    .with_err_msg("could not write commit")
            }
            Object::Tree(tree) => {
                let size = tree.size();
                write!(writer, "tree {size}\x00")?;

                tree.write_to(writer).with_err_msg("could not write tree")
            }
            Object::Blob(blob) => {
                let size = blob.content.len();
                write!(writer, "blob {size}\x00")?;

                writer
                    .write_all(&blob.content)
                    .with_err_msg("could not write blob")
            }
            Object::Tag(tag) => {
                let size = tag.tag.size();
                write!(writer, "tag {size}\x00")?;

                tag.tag
                    .write_to(&mut writer)
                    .with_err_msg("could not write tag")
            }
        }
    }

    #[must_use]
    pub fn size(&self) -> u64 {
        match self {
            Self::Commit(commit) => commit.size(),
            Self::Tree(tree) => tree.size(),
            Self::Blob(blob) => blob.size(),
            Self::Tag(tag) => tag.size(),
        }
    }
}