1use crate::core::{find_repo_root, Object, ObjectHash};
2use crate::response::{ShowResponse, TreeEntryInfo};
3use crate::storage::ObjectStore;
4
5fn resolve_object(
14 repo_root: &std::path::Path,
15 object: String,
16) -> Result<ObjectHash, crate::errors::LitError> {
17 use crate::core::{read_head, read_ref};
18
19 if object == "HEAD" {
20 let head = read_head(repo_root)?;
22 return Ok(match read_ref(repo_root, &format!("heads/{}", head)) {
23 Ok(hash) => ObjectHash::from_hex(hash),
24 Err(_) => ObjectHash::from_hex(head),
25 });
26 }
27
28 let resolved = read_ref(repo_root, &format!("heads/{}", object))
30 .or_else(|_| read_ref(repo_root, &format!("tags/{}", object)))
31 .unwrap_or(object);
32 Ok(ObjectHash::from_hex(resolved))
33}
34
35pub fn execute(object: String) -> Result<ShowResponse, crate::errors::LitError> {
36 let repo_root = find_repo_root()?;
37 let store = ObjectStore::new(&repo_root);
38
39 let hash = resolve_object(&repo_root, object)?;
40
41 let obj = store.read(&hash)?;
42
43 match obj {
44 Object::Commit(commit) => Ok(ShowResponse::Commit {
45 hash: hash.to_string(),
46 author: commit.author,
47 timestamp: commit.timestamp,
48 message: commit.message,
49 }),
50 Object::Tree(tree) => {
51 let entries = tree
52 .entries
53 .into_iter()
54 .map(|e| TreeEntryInfo {
55 mode: e.mode,
56 object_type: e.object_type,
57 hash: e.hash.to_string(),
58 name: e.name,
59 })
60 .collect();
61 Ok(ShowResponse::Tree {
62 hash: hash.to_string(),
63 entries,
64 })
65 }
66 Object::Blob(blob) => {
67 let content = std::str::from_utf8(&blob.content)
68 .map(|s| s.to_string())
69 .ok();
70 let is_binary = content.is_none();
71 Ok(ShowResponse::Blob {
72 hash: hash.to_string(),
73 size: blob.content.len(),
74 content,
75 is_binary,
76 })
77 }
78 Object::Tag(tag) => Ok(ShowResponse::Commit {
79 hash: hash.to_string(),
80 author: tag.tagger.clone(),
81 timestamp: tag.timestamp,
82 message: format!(
83 "tag {}\nTarget: {}\n\n{}",
84 tag.tag_name,
85 tag.target.as_str(),
86 tag.message
87 ),
88 }),
89 }
90}