xei_core/
call_hierarchy.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum CallDirection {
5 Incoming,
6 Outgoing,
7}
8
9impl CallDirection {
10 pub fn label(self) -> &'static str {
11 match self {
12 CallDirection::Incoming => "incoming",
13 CallDirection::Outgoing => "outgoing",
14 }
15 }
16
17 pub fn toggle(self) -> Self {
18 match self {
19 CallDirection::Incoming => CallDirection::Outgoing,
20 CallDirection::Outgoing => CallDirection::Incoming,
21 }
22 }
23}
24
25#[derive(Debug, Clone)]
26pub struct CallItem {
27 pub name: String,
28 pub detail: String,
29 pub kind: String,
30 pub path: String,
31 pub row: usize,
32 pub col: usize,
33 pub raw_json: String,
35}
36
37#[derive(Debug, Clone)]
38pub struct CallHierarchyState {
39 pub open: bool,
40 pub direction: CallDirection,
41 pub root_name: String,
42 pub items: Vec<CallItem>,
43 pub selected: usize,
44 pub loading: bool,
45 pub message: String,
46}
47
48impl Default for CallHierarchyState {
49 fn default() -> Self {
50 Self {
51 open: false,
52 direction: CallDirection::Incoming,
53 root_name: String::new(),
54 items: Vec::new(),
55 selected: 0,
56 loading: false,
57 message: String::new(),
58 }
59 }
60}
61
62impl CallHierarchyState {
63 pub fn new() -> Self {
64 Self::default()
65 }
66
67 pub fn close(&mut self) {
68 self.open = false;
69 self.items.clear();
70 self.loading = false;
71 self.message.clear();
72 }
73
74 pub fn begin(&mut self, root_name: &str, direction: CallDirection) {
75 self.open = true;
76 self.direction = direction;
77 self.root_name = root_name.to_string();
78 self.items.clear();
79 self.selected = 0;
80 self.loading = true;
81 self.message = format!("Call hierarchy ({})…", direction.label());
82 }
83
84 pub fn set_items(&mut self, items: Vec<CallItem>) {
85 self.items = items;
86 self.selected = 0;
87 self.loading = false;
88 self.message = if self.items.is_empty() {
89 format!("No {} calls", self.direction.label())
90 } else {
91 format!(
92 "{} · {} {} call(s)",
93 self.root_name,
94 self.items.len(),
95 self.direction.label()
96 )
97 };
98 }
99
100 pub fn move_sel(&mut self, delta: isize) {
101 if self.items.is_empty() {
102 return;
103 }
104 let n = self.items.len() as isize;
105 let cur = self.selected as isize + delta;
106 self.selected = cur.rem_euclid(n) as usize;
107 }
108
109 pub fn selected_item(&self) -> Option<&CallItem> {
110 self.items.get(self.selected)
111 }
112}