git_traverse/tree/
mod.rs

1use std::collections::VecDeque;
2
3use git_object::bstr::{BStr, BString};
4
5/// A trait to allow responding to a traversal designed to observe all entries in a tree, recursively while keeping track of
6/// paths if desired.
7pub trait Visit {
8    /// Sets the full path path in front of the queue so future calls to push and pop components affect it instead.
9    fn pop_front_tracked_path_and_set_current(&mut self);
10    /// Append a `component` to the end of a path, which may be empty.
11    fn push_back_tracked_path_component(&mut self, component: &BStr);
12    /// Append a `component` to the end of a path, which may be empty.
13    fn push_path_component(&mut self, component: &BStr);
14    /// Removes the last component from the path, which may leave it empty.
15    fn pop_path_component(&mut self);
16
17    /// Observe a tree entry that is a tree and return an instruction whether to continue or not.
18    /// [`Action::Skip`][visit::Action::Skip] can be used to prevent traversing it, for example if it's known to the caller already.
19    ///
20    /// The implementation may use the current path to learn where in the tree the change is located.
21    fn visit_tree(&mut self, entry: &git_object::tree::EntryRef<'_>) -> visit::Action;
22
23    /// Observe a tree entry that is NO tree and return an instruction whether to continue or not.
24    /// [`Action::Skip`][visit::Action::Skip] has no effect here.
25    ///
26    /// The implementation may use the current path to learn where in the tree the change is located.
27    fn visit_nontree(&mut self, entry: &git_object::tree::EntryRef<'_>) -> visit::Action;
28}
29
30/// A [Visit][Visit] implementation to record every observed change and keep track of the changed paths.
31#[derive(Clone, Debug, Default)]
32pub struct Recorder {
33    path_deque: VecDeque<BString>,
34    path: BString,
35    /// The observed entries.
36    pub records: Vec<recorder::Entry>,
37}
38
39///
40pub mod visit {
41    /// What to do after an entry was [recorded][super::Visit::visit_tree()].
42    #[derive(Clone, Copy, PartialOrd, PartialEq, Ord, Eq, Hash)]
43    pub enum Action {
44        /// Continue the traversal of entries.
45        Continue,
46        /// Stop the traversal of entries, making this te last call to [`visit_(tree|nontree)(…)`][super::Visit::visit_nontree()].
47        Cancel,
48        /// Don't dive into the entry, skipping children effectively. Only useful in [`visit_tree(…)`][super::Visit::visit_tree()].
49        Skip,
50    }
51
52    impl Action {
53        /// Returns true if this action means to stop the traversal.
54        pub fn cancelled(&self) -> bool {
55            matches!(self, Action::Cancel)
56        }
57    }
58}
59
60///
61pub mod recorder;
62
63///
64pub mod breadthfirst;
65pub use breadthfirst::impl_::traverse as breadthfirst;