sl_up/
smartlog.rs

1use crate::{
2    graph::{Item, ItemType},
3    parser::SmartLogParser,
4};
5
6#[derive(Debug)]
7pub struct SmartLog {
8    pub items: Vec<ItemType>,
9    selection_idx: usize,
10}
11
12impl SmartLog {
13    pub fn new(raw_lines: &[String]) -> Self {
14        let items = SmartLogParser::parse(raw_lines).unwrap();
15        let selection_idx = Self::get_selected_item_index(&items).unwrap();
16        Self {
17            items,
18            selection_idx,
19        }
20    }
21
22    pub fn get_selected_commit_hash(&self) -> Option<&str> {
23        let item = self.items.get(self.selection_idx).unwrap();
24        if let ItemType::Commit(commit) = item {
25            return commit.hash();
26        }
27        None
28    }
29
30    pub fn move_up(&mut self) {
31        if self.selection_idx > 0 {
32            let mut selection_candidate = self.selection_idx;
33            for i in (0..self.selection_idx).rev() {
34                if let ItemType::Commit(_) = self.items[i] {
35                    selection_candidate = i;
36                    break;
37                }
38            }
39            if selection_candidate == self.selection_idx {
40                return;
41            }
42
43            self.deselect_line_idx(self.selection_idx);
44            self.select_line_index(selection_candidate);
45        }
46    }
47
48    pub fn move_down(&mut self) {
49        if self.selection_idx < self.items.len() - 1 {
50            let mut selection_candidate = self.selection_idx;
51            for i in (self.selection_idx + 1)..self.items.len() {
52                if let ItemType::Commit(_) = self.items[i] {
53                    selection_candidate = i;
54                    break;
55                }
56            }
57            if selection_candidate == self.selection_idx {
58                return;
59            }
60
61            self.deselect_line_idx(self.selection_idx);
62            self.select_line_index(selection_candidate);
63        }
64    }
65
66    pub fn to_string_vec(&self) -> Vec<String> {
67        self.items
68            .iter()
69            .flat_map(|item| item.to_string_vec())
70            .collect()
71    }
72
73    pub fn select_line_index(&mut self, item_idx: usize) {
74        let item = self.items.get_mut(item_idx).unwrap();
75        if let ItemType::Commit(commit) = item {
76            commit.select();
77            self.selection_idx = item_idx;
78        }
79    }
80
81    pub fn deselect_line_idx(&mut self, item_idx: usize) {
82        let item = self.items.get_mut(item_idx).unwrap();
83        if let ItemType::Commit(commit) = item {
84            commit.deselect();
85        }
86    }
87
88    fn get_selected_item_index(items: &[ItemType]) -> Option<usize> {
89        for (idx, item) in items.iter().enumerate() {
90            if let ItemType::Commit(commit) = item {
91                if commit.selected {
92                    return Some(idx);
93                }
94            }
95        }
96        None
97    }
98}