git_traverse/tree/
recorder.rs1use git_hash::ObjectId;
2use git_object::{
3 bstr::{BStr, BString, ByteSlice, ByteVec},
4 tree,
5};
6
7use crate::tree::{visit::Action, Recorder, Visit};
8
9#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct Entry {
13 pub mode: tree::EntryMode,
15 pub filepath: BString,
19 pub oid: ObjectId,
21}
22
23impl Entry {
24 fn new(entry: &tree::EntryRef<'_>, filepath: BString) -> Self {
25 Entry {
26 filepath,
27 oid: entry.oid.to_owned(),
28 mode: entry.mode,
29 }
30 }
31}
32
33impl Recorder {
34 fn pop_element(&mut self) {
35 if let Some(pos) = self.path.rfind_byte(b'/') {
36 self.path.resize(pos, 0);
37 } else {
38 self.path.clear();
39 }
40 }
41
42 fn push_element(&mut self, name: &BStr) {
43 if !self.path.is_empty() {
44 self.path.push(b'/');
45 }
46 self.path.push_str(name);
47 }
48
49 fn path_clone(&self) -> BString {
50 self.path.clone()
51 }
52}
53
54impl Visit for Recorder {
55 fn pop_front_tracked_path_and_set_current(&mut self) {
56 self.path = self
57 .path_deque
58 .pop_front()
59 .expect("every call is matched with push_tracked_path_component");
60 }
61
62 fn push_back_tracked_path_component(&mut self, component: &BStr) {
63 self.push_element(component);
64 self.path_deque.push_back(self.path.clone());
65 }
66
67 fn push_path_component(&mut self, component: &BStr) {
68 self.push_element(component);
69 }
70
71 fn pop_path_component(&mut self) {
72 self.pop_element();
73 }
74
75 fn visit_tree(&mut self, entry: &tree::EntryRef<'_>) -> Action {
76 self.records.push(Entry::new(entry, self.path_clone()));
77 Action::Continue
78 }
79
80 fn visit_nontree(&mut self, entry: &tree::EntryRef<'_>) -> Action {
81 self.records.push(Entry::new(entry, self.path_clone()));
82 Action::Continue
83 }
84}