@@ -19,3 +19,145 @@ pub struct ObjectID {
1919 pub hash : [ u8 ; GIT_MAX_RAWSZ ] ,
2020 pub algo : u32 ,
2121}
22+
23+ #[ allow( dead_code) ]
24+ impl ObjectID {
25+ pub fn as_slice ( & self ) -> & [ u8 ] {
26+ match HashAlgorithm :: from_u32 ( self . algo ) {
27+ Some ( algo) => & self . hash [ 0 ..algo. raw_len ( ) ] ,
28+ None => & self . hash ,
29+ }
30+ }
31+
32+ pub fn as_mut_slice ( & mut self ) -> & mut [ u8 ] {
33+ match HashAlgorithm :: from_u32 ( self . algo ) {
34+ Some ( algo) => & mut self . hash [ 0 ..algo. raw_len ( ) ] ,
35+ None => & mut self . hash ,
36+ }
37+ }
38+ }
39+
40+ /// A hash algorithm,
41+ #[ repr( C ) ]
42+ #[ derive( Debug , Copy , Clone , Ord , PartialOrd , Eq , PartialEq ) ]
43+ pub enum HashAlgorithm {
44+ SHA1 = 1 ,
45+ SHA256 = 2 ,
46+ }
47+
48+ #[ allow( dead_code) ]
49+ impl HashAlgorithm {
50+ const SHA1_NULL_OID : ObjectID = ObjectID {
51+ hash : [ 0u8 ; 32 ] ,
52+ algo : Self :: SHA1 as u32 ,
53+ } ;
54+ const SHA256_NULL_OID : ObjectID = ObjectID {
55+ hash : [ 0u8 ; 32 ] ,
56+ algo : Self :: SHA256 as u32 ,
57+ } ;
58+
59+ const SHA1_EMPTY_TREE : ObjectID = ObjectID {
60+ hash : * b"\x4b \x82 \x5d \xc6 \x42 \xcb \x6e \xb9 \xa0 \x60 \xe5 \x4b \xf8 \xd6 \x92 \x88 \xfb \xee \x49 \x04 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ,
61+ algo : Self :: SHA1 as u32 ,
62+ } ;
63+ const SHA256_EMPTY_TREE : ObjectID = ObjectID {
64+ hash : * b"\x6e \xf1 \x9b \x41 \x22 \x5c \x53 \x69 \xf1 \xc1 \x04 \xd4 \x5d \x8d \x85 \xef \xa9 \xb0 \x57 \xb5 \x3b \x14 \xb4 \xb9 \xb9 \x39 \xdd \x74 \xde \xcc \x53 \x21 " ,
65+ algo : Self :: SHA256 as u32 ,
66+ } ;
67+
68+ const SHA1_EMPTY_BLOB : ObjectID = ObjectID {
69+ hash : * b"\xe6 \x9d \xe2 \x9b \xb2 \xd1 \xd6 \x43 \x4b \x8b \x29 \xae \x77 \x5a \xd8 \xc2 \xe4 \x8c \x53 \x91 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ,
70+ algo : Self :: SHA1 as u32 ,
71+ } ;
72+ const SHA256_EMPTY_BLOB : ObjectID = ObjectID {
73+ hash : * b"\x47 \x3a \x0f \x4c \x3b \xe8 \xa9 \x36 \x81 \xa2 \x67 \xe3 \xb1 \xe9 \xa7 \xdc \xda \x11 \x85 \x43 \x6f \xe1 \x41 \xf7 \x74 \x91 \x20 \xa3 \x03 \x72 \x18 \x13 " ,
74+ algo : Self :: SHA256 as u32 ,
75+ } ;
76+
77+ /// Return a hash algorithm based on the internal integer ID used by Git.
78+ ///
79+ /// Returns `None` if the algorithm doesn't indicate a valid algorithm.
80+ pub const fn from_u32 ( algo : u32 ) -> Option < HashAlgorithm > {
81+ match algo {
82+ 1 => Some ( HashAlgorithm :: SHA1 ) ,
83+ 2 => Some ( HashAlgorithm :: SHA256 ) ,
84+ _ => None ,
85+ }
86+ }
87+
88+ /// Return a hash algorithm based on the internal integer ID used by Git.
89+ ///
90+ /// Returns `None` if the algorithm doesn't indicate a valid algorithm.
91+ pub const fn from_format_id ( algo : u32 ) -> Option < HashAlgorithm > {
92+ match algo {
93+ 0x73686131 => Some ( HashAlgorithm :: SHA1 ) ,
94+ 0x73323536 => Some ( HashAlgorithm :: SHA256 ) ,
95+ _ => None ,
96+ }
97+ }
98+
99+ /// The name of this hash algorithm as a string suitable for the configuration file.
100+ pub const fn name ( self ) -> & ' static str {
101+ match self {
102+ HashAlgorithm :: SHA1 => "sha1" ,
103+ HashAlgorithm :: SHA256 => "sha256" ,
104+ }
105+ }
106+
107+ /// The format ID of this algorithm for binary formats.
108+ ///
109+ /// Note that when writing this to a data format, it should be written in big-endian format
110+ /// explicitly.
111+ pub const fn format_id ( self ) -> u32 {
112+ match self {
113+ HashAlgorithm :: SHA1 => 0x73686131 ,
114+ HashAlgorithm :: SHA256 => 0x73323536 ,
115+ }
116+ }
117+
118+ /// The length of binary object IDs in this algorithm in bytes.
119+ pub const fn raw_len ( self ) -> usize {
120+ match self {
121+ HashAlgorithm :: SHA1 => 20 ,
122+ HashAlgorithm :: SHA256 => 32 ,
123+ }
124+ }
125+
126+ /// The length of object IDs in this algorithm in hexadecimal characters.
127+ pub const fn hex_len ( self ) -> usize {
128+ self . raw_len ( ) * 2
129+ }
130+
131+ /// The number of bytes which is processed by one iteration of this algorithm's compression
132+ /// function.
133+ pub const fn block_size ( self ) -> usize {
134+ match self {
135+ HashAlgorithm :: SHA1 => 64 ,
136+ HashAlgorithm :: SHA256 => 64 ,
137+ }
138+ }
139+
140+ /// The object ID representing the empty blob.
141+ pub const fn empty_blob ( self ) -> & ' static ObjectID {
142+ match self {
143+ HashAlgorithm :: SHA1 => & Self :: SHA1_EMPTY_BLOB ,
144+ HashAlgorithm :: SHA256 => & Self :: SHA256_EMPTY_BLOB ,
145+ }
146+ }
147+
148+ /// The object ID representing the empty tree.
149+ pub const fn empty_tree ( self ) -> & ' static ObjectID {
150+ match self {
151+ HashAlgorithm :: SHA1 => & Self :: SHA1_EMPTY_TREE ,
152+ HashAlgorithm :: SHA256 => & Self :: SHA256_EMPTY_TREE ,
153+ }
154+ }
155+
156+ /// The object ID which is all zeros.
157+ pub const fn null_oid ( self ) -> & ' static ObjectID {
158+ match self {
159+ HashAlgorithm :: SHA1 => & Self :: SHA1_NULL_OID ,
160+ HashAlgorithm :: SHA256 => & Self :: SHA256_NULL_OID ,
161+ }
162+ }
163+ }
0 commit comments