git_internal/internal/object/
types.rs1use std::fmt::Display;
5
6use serde::{Deserialize, Serialize};
7
8use crate::errors::GitError;
9
10#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, Serialize, Deserialize)]
29pub enum ObjectType {
30 Commit = 1,
31 Tree,
32 Blob,
33 Tag,
34 OffsetZstdelta, OffsetDelta,
36 HashDelta,
37}
38
39const COMMIT_OBJECT_TYPE: &[u8] = b"commit";
40const TREE_OBJECT_TYPE: &[u8] = b"tree";
41const BLOB_OBJECT_TYPE: &[u8] = b"blob";
42const TAG_OBJECT_TYPE: &[u8] = b"tag";
43
44impl Display for ObjectType {
46 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
47 match self {
48 ObjectType::Blob => write!(f, "blob"),
49 ObjectType::Tree => write!(f, "tree"),
50 ObjectType::Commit => write!(f, "commit"),
51 ObjectType::Tag => write!(f, "tag"),
52 ObjectType::OffsetZstdelta => write!(f, "OffsetZstdelta"),
53 ObjectType::OffsetDelta => write!(f, "OffsetDelta"),
54 ObjectType::HashDelta => write!(f, "HashDelta"),
55 }
56 }
57}
58
59impl ObjectType {
61 pub fn to_bytes(&self) -> &[u8] {
62 match self {
63 ObjectType::Commit => COMMIT_OBJECT_TYPE,
64 ObjectType::Tree => TREE_OBJECT_TYPE,
65 ObjectType::Blob => BLOB_OBJECT_TYPE,
66 ObjectType::Tag => TAG_OBJECT_TYPE,
67 _ => panic!("can put compute the delta hash value"),
68 }
69 }
70
71 pub fn from_string(s: &str) -> Result<ObjectType, GitError> {
73 match s {
74 "blob" => Ok(ObjectType::Blob),
75 "tree" => Ok(ObjectType::Tree),
76 "commit" => Ok(ObjectType::Commit),
77 "tag" => Ok(ObjectType::Tag),
78 _ => Err(GitError::InvalidObjectType(s.to_string())),
79 }
80 }
81
82 pub fn to_data(self) -> Result<Vec<u8>, GitError> {
84 match self {
85 ObjectType::Blob => Ok(vec![0x62, 0x6c, 0x6f, 0x62]),
86 ObjectType::Tree => Ok(vec![0x74, 0x72, 0x65, 0x65]),
87 ObjectType::Commit => Ok(vec![0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74]),
88 ObjectType::Tag => Ok(vec![0x74, 0x61, 0x67]),
89 _ => Err(GitError::InvalidObjectType(self.to_string())),
90 }
91 }
92
93 pub fn to_u8(&self) -> u8 {
95 match self {
96 ObjectType::Commit => 1,
97 ObjectType::Tree => 2,
98 ObjectType::Blob => 3,
99 ObjectType::Tag => 4,
100 ObjectType::OffsetZstdelta => 5, ObjectType::OffsetDelta => 6,
102 ObjectType::HashDelta => 7,
103 }
104 }
105
106 pub fn from_u8(number: u8) -> Result<ObjectType, GitError> {
108 match number {
109 1 => Ok(ObjectType::Commit),
110 2 => Ok(ObjectType::Tree),
111 3 => Ok(ObjectType::Blob),
112 4 => Ok(ObjectType::Tag),
113 5 => Ok(ObjectType::OffsetZstdelta),
114 6 => Ok(ObjectType::OffsetDelta),
115 7 => Ok(ObjectType::HashDelta),
116 _ => Err(GitError::InvalidObjectType(format!(
117 "Invalid object type number: {number}"
118 ))),
119 }
120 }
121
122 pub fn is_base(&self) -> bool {
123 match self {
124 ObjectType::Commit => true,
125 ObjectType::Tree => true,
126 ObjectType::Blob => true,
127 ObjectType::Tag => true,
128 ObjectType::HashDelta => false,
129 ObjectType::OffsetZstdelta => false,
130 ObjectType::OffsetDelta => false,
131 }
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use crate::internal::object::types::ObjectType;
138
139 #[test]
141 fn test_object_type_to_data() {
142 let blob = ObjectType::Blob;
143 let blob_bytes = blob.to_data().unwrap();
144 assert_eq!(blob_bytes, vec![0x62, 0x6c, 0x6f, 0x62]);
145 }
146
147 #[test]
149 fn test_object_type_from_string() {
150 let tree = ObjectType::from_string("tree").unwrap();
151 assert_eq!(tree, ObjectType::Tree);
152 }
153
154 #[test]
156 fn test_object_type_to_u8() {
157 let commit = ObjectType::Commit;
158 let commit_number = commit.to_u8();
159 assert_eq!(commit_number, 1);
160 }
161
162 #[test]
164 fn test_object_type_from_u8() {
165 let tag_number = 4;
166 let tag = ObjectType::from_u8(tag_number).unwrap();
167 assert_eq!(tag, ObjectType::Tag);
168 }
169}