Skip to main content

rustlens_lib/ui/app/
types.rs

1//! Shared UI types: tabs, focus.
2
3/// Active tab in the UI (Crates = project crates from Cargo.toml + open crate items)
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5pub enum Tab {
6    #[default]
7    Types,
8    Functions,
9    Modules,
10    Crates,
11}
12
13impl Tab {
14    pub fn all() -> &'static [Tab] {
15        &[Tab::Types, Tab::Functions, Tab::Modules, Tab::Crates]
16    }
17
18    pub fn title(&self) -> &'static str {
19        match self {
20            Tab::Types => "Types",
21            Tab::Functions => "Functions",
22            Tab::Modules => "Modules",
23            Tab::Crates => "Crates",
24        }
25    }
26
27    pub fn index(&self) -> usize {
28        match self {
29            Tab::Types => 0,
30            Tab::Functions => 1,
31            Tab::Modules => 2,
32            Tab::Crates => 3,
33        }
34    }
35
36    pub fn from_index(index: usize) -> Self {
37        match index % 4 {
38            0 => Tab::Types,
39            1 => Tab::Functions,
40            2 => Tab::Modules,
41            _ => Tab::Crates,
42        }
43    }
44
45    pub fn next(&self) -> Self {
46        Self::from_index(self.index() + 1)
47    }
48
49    pub fn prev(&self) -> Self {
50        Self::from_index(self.index().wrapping_sub(1).min(3))
51    }
52}
53
54/// Focus state for keyboard navigation
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
56pub enum Focus {
57    #[default]
58    Search,
59    List,
60    Inspector,
61    /// In-TUI Copilot chat panel (only when copilot_chat_open)
62    CopilotChat,
63}
64
65impl Focus {
66    /// Next focus; when `copilot_chat_open` is true, Inspector -> CopilotChat -> Search.
67    pub fn next(&self, copilot_chat_open: bool) -> Self {
68        match self {
69            Focus::Search => Focus::List,
70            Focus::List => Focus::Inspector,
71            Focus::Inspector => {
72                if copilot_chat_open {
73                    Focus::CopilotChat
74                } else {
75                    Focus::Search
76                }
77            }
78            Focus::CopilotChat => Focus::Search,
79        }
80    }
81
82    /// Previous focus.
83    pub fn prev(&self, copilot_chat_open: bool) -> Self {
84        match self {
85            Focus::Search => {
86                if copilot_chat_open {
87                    Focus::CopilotChat
88                } else {
89                    Focus::Inspector
90                }
91            }
92            Focus::List => Focus::Search,
93            Focus::Inspector => Focus::List,
94            Focus::CopilotChat => Focus::Inspector,
95        }
96    }
97}