1pub mod blob;
4pub mod commit;
5pub mod oid;
6pub mod store;
7pub mod tag_object;
8pub mod tree;
9
10pub use blob::Blob;
11pub use commit::{Commit, Signature};
12pub use oid::Oid;
13pub use store::{LooseObjectStore, ObjectType, RawObject};
14pub use tag_object::TagObject;
15pub use tree::{FileMode, Tree, TreeEntry};
16
17#[derive(Debug, Clone)]
22pub enum Object {
23 Blob(Blob),
25 Tree(Tree),
27 Commit(Commit),
29}
30
31impl Object {
32 pub fn kind(&self) -> ObjectType {
34 match self {
35 Object::Blob(_) => ObjectType::Blob,
36 Object::Tree(_) => ObjectType::Tree,
37 Object::Commit(_) => ObjectType::Commit,
38 }
39 }
40
41 pub fn as_blob(&self) -> Option<&Blob> {
43 match self {
44 Object::Blob(blob) => Some(blob),
45 _ => None,
46 }
47 }
48
49 pub fn as_tree(&self) -> Option<&Tree> {
51 match self {
52 Object::Tree(tree) => Some(tree),
53 _ => None,
54 }
55 }
56
57 pub fn as_commit(&self) -> Option<&Commit> {
59 match self {
60 Object::Commit(commit) => Some(commit),
61 _ => None,
62 }
63 }
64
65 pub fn into_blob(self) -> Option<Blob> {
67 match self {
68 Object::Blob(blob) => Some(blob),
69 _ => None,
70 }
71 }
72
73 pub fn into_tree(self) -> Option<Tree> {
75 match self {
76 Object::Tree(tree) => Some(tree),
77 _ => None,
78 }
79 }
80
81 pub fn into_commit(self) -> Option<Commit> {
83 match self {
84 Object::Commit(commit) => Some(commit),
85 _ => None,
86 }
87 }
88}
89
90impl From<Blob> for Object {
91 fn from(blob: Blob) -> Self {
92 Object::Blob(blob)
93 }
94}
95
96impl From<Tree> for Object {
97 fn from(tree: Tree) -> Self {
98 Object::Tree(tree)
99 }
100}
101
102impl From<Commit> for Object {
103 fn from(commit: Commit) -> Self {
104 Object::Commit(commit)
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111 use store::RawObject;
112
113 fn make_blob_raw(content: &[u8]) -> RawObject {
114 RawObject {
115 object_type: ObjectType::Blob,
116 content: content.to_vec(),
117 }
118 }
119
120 fn make_tree_raw() -> RawObject {
121 RawObject {
122 object_type: ObjectType::Tree,
123 content: vec![],
124 }
125 }
126
127 fn make_commit_raw() -> RawObject {
128 let content = "tree da39a3ee5e6b4b0d3255bfef95601890afd80709\n\
129 author John Doe <john@example.com> 1234567890 +0000\n\
130 committer John Doe <john@example.com> 1234567890 +0000\n\
131 \n\
132 Test commit";
133 RawObject {
134 object_type: ObjectType::Commit,
135 content: content.as_bytes().to_vec(),
136 }
137 }
138
139 fn dummy_oid() -> Oid {
140 Oid::from_hex("0123456789abcdef0123456789abcdef01234567").unwrap()
141 }
142
143 #[test]
145 fn test_object_from_blob() {
146 let blob = Blob::parse(make_blob_raw(b"Hello")).unwrap();
147 let obj = Object::from(blob);
148 assert!(matches!(obj, Object::Blob(_)));
149 }
150
151 #[test]
153 fn test_object_from_tree() {
154 let tree = Tree::parse(make_tree_raw()).unwrap();
155 let obj = Object::from(tree);
156 assert!(matches!(obj, Object::Tree(_)));
157 }
158
159 #[test]
161 fn test_object_from_commit() {
162 let commit = Commit::parse(dummy_oid(), make_commit_raw()).unwrap();
163 let obj = Object::from(commit);
164 assert!(matches!(obj, Object::Commit(_)));
165 }
166
167 #[test]
169 fn test_kind() {
170 let blob = Object::from(Blob::parse(make_blob_raw(b"test")).unwrap());
171 assert_eq!(blob.kind(), ObjectType::Blob);
172
173 let tree = Object::from(Tree::parse(make_tree_raw()).unwrap());
174 assert_eq!(tree.kind(), ObjectType::Tree);
175
176 let commit = Object::from(Commit::parse(dummy_oid(), make_commit_raw()).unwrap());
177 assert_eq!(commit.kind(), ObjectType::Commit);
178 }
179
180 #[test]
182 fn test_as_blob() {
183 let blob_obj = Object::from(Blob::parse(make_blob_raw(b"test")).unwrap());
184 assert!(blob_obj.as_blob().is_some());
185 assert!(blob_obj.as_tree().is_none());
186 assert!(blob_obj.as_commit().is_none());
187 }
188
189 #[test]
191 fn test_as_tree() {
192 let tree_obj = Object::from(Tree::parse(make_tree_raw()).unwrap());
193 assert!(tree_obj.as_tree().is_some());
194 assert!(tree_obj.as_blob().is_none());
195 assert!(tree_obj.as_commit().is_none());
196 }
197
198 #[test]
200 fn test_as_commit() {
201 let commit_obj = Object::from(Commit::parse(dummy_oid(), make_commit_raw()).unwrap());
202 assert!(commit_obj.as_commit().is_some());
203 assert!(commit_obj.as_blob().is_none());
204 assert!(commit_obj.as_tree().is_none());
205 }
206
207 #[test]
209 fn test_into_blob() {
210 let blob_obj = Object::from(Blob::parse(make_blob_raw(b"test")).unwrap());
211 let blob = blob_obj.into_blob();
212 assert!(blob.is_some());
213 assert_eq!(blob.unwrap().content(), b"test");
214
215 let tree_obj = Object::from(Tree::parse(make_tree_raw()).unwrap());
216 assert!(tree_obj.into_blob().is_none());
217 }
218
219 #[test]
221 fn test_into_tree() {
222 let tree_obj = Object::from(Tree::parse(make_tree_raw()).unwrap());
223 let tree = tree_obj.into_tree();
224 assert!(tree.is_some());
225 assert!(tree.unwrap().is_empty());
226
227 let blob_obj = Object::from(Blob::parse(make_blob_raw(b"test")).unwrap());
228 assert!(blob_obj.into_tree().is_none());
229 }
230
231 #[test]
233 fn test_into_commit() {
234 let commit_obj = Object::from(Commit::parse(dummy_oid(), make_commit_raw()).unwrap());
235 let commit = commit_obj.into_commit();
236 assert!(commit.is_some());
237 assert_eq!(commit.unwrap().summary(), "Test commit");
238
239 let blob_obj = Object::from(Blob::parse(make_blob_raw(b"test")).unwrap());
240 assert!(blob_obj.into_commit().is_none());
241 }
242
243 #[test]
245 fn test_as_methods_return_references() {
246 let blob_obj = Object::from(Blob::parse(make_blob_raw(b"content")).unwrap());
247 let blob_ref = blob_obj.as_blob().unwrap();
248 assert_eq!(blob_ref.content(), b"content");
249
250 assert_eq!(blob_obj.kind(), ObjectType::Blob);
252 }
253}