rskit-git 0.2.0-alpha.3

Composable git repository interfaces backed by libgit2
Documentation
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use crate::types::{Commit, Oid, Reference, Signature};

pub(crate) fn oid_from_git2(oid: git2::Oid) -> Oid {
    let mut bytes = [0u8; 20];
    bytes.copy_from_slice(oid.as_bytes());
    Oid::from_bytes(bytes)
}

pub(crate) fn signature_from_git2(signature: &git2::Signature<'_>) -> Signature {
    Signature {
        name: signature.name().unwrap_or_default().to_string(),
        email: signature.email().unwrap_or_default().to_string(),
        when: system_time_from_git2(signature.when()),
    }
}

pub(crate) fn commit_from_git2(commit: &git2::Commit<'_>) -> Commit {
    Commit {
        oid: oid_from_git2(commit.id()),
        author: signature_from_git2(&commit.author()),
        committer: signature_from_git2(&commit.committer()),
        message: commit
            .message()
            .unwrap_or_default()
            .trim_end_matches('\n')
            .trim_end_matches('\0')
            .to_string(),
        parents: commit.parent_ids().map(oid_from_git2).collect(),
    }
}
pub(crate) fn reference_from_git2(reference: &git2::Reference<'_>) -> Reference {
    let name = reference.name().unwrap_or("HEAD").to_string();
    let target = reference
        .resolve()
        .ok()
        .and_then(|resolved| resolved.target())
        .or_else(|| reference.target())
        .map(oid_from_git2)
        .unwrap_or_else(|| Oid::from_bytes([0; 20]));
    Reference {
        name,
        target,
        is_branch: reference.is_branch(),
        is_tag: reference.is_tag(),
    }
}

pub(crate) fn system_time_from_git2(time: git2::Time) -> SystemTime {
    let seconds = time.seconds();
    if seconds >= 0 {
        UNIX_EPOCH + Duration::from_secs(seconds as u64)
    } else {
        UNIX_EPOCH - Duration::from_secs(seconds.unsigned_abs())
    }
}