1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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",
}
}
}