use std::cmp::Ordering;
use crate::{
bstr::{BStr, BString},
tree,
};
mod ref_iter;
pub mod write;
#[derive(Clone, Copy, PartialEq, Eq, Debug, Ord, PartialOrd, Hash)]
#[repr(u16)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub enum EntryMode {
Tree = 0o040000u16,
Blob = 0o100644,
BlobExecutable = 0o100755,
Link = 0o120000,
Commit = 0o160000,
}
impl EntryMode {
pub fn is_tree(&self) -> bool {
*self == EntryMode::Tree
}
pub fn is_no_tree(&self) -> bool {
*self != EntryMode::Tree
}
pub fn is_blob(&self) -> bool {
matches!(self, EntryMode::Blob | EntryMode::BlobExecutable)
}
pub fn as_str(&self) -> &'static str {
use EntryMode::*;
match self {
Tree => "tree",
Blob => "blob",
BlobExecutable => "exe",
Link => "link",
Commit => "commit",
}
}
}
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct EntryRef<'a> {
pub mode: tree::EntryMode,
pub filename: &'a BStr,
#[cfg_attr(feature = "serde1", serde(borrow))]
pub oid: &'a git_hash::oid,
}
impl<'a> PartialOrd for EntryRef<'a> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<'a> Ord for EntryRef<'a> {
fn cmp(&self, other: &Self) -> Ordering {
let len = self.filename.len().min(other.filename.len());
self.filename[..len].cmp(&other.filename[..len])
}
}
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct Entry {
pub mode: EntryMode,
pub filename: BString,
pub oid: git_hash::ObjectId,
}
impl PartialOrd for Entry {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Entry {
fn cmp(&self, other: &Self) -> Ordering {
let common_len = self.filename.len().min(other.filename.len());
self.filename[..common_len]
.cmp(&other.filename[..common_len])
.then_with(|| self.filename.len().cmp(&other.filename.len()))
}
}
impl EntryMode {
pub fn as_bytes(&self) -> &'static [u8] {
use EntryMode::*;
match self {
Tree => b"40000",
Blob => b"100644",
BlobExecutable => b"100755",
Link => b"120000",
Commit => b"160000",
}
}
}