sql_cli/ui/utils/
scroll_utils.rs1#[must_use]
4pub fn calculate_horizontal_scroll(cursor_pos: usize, terminal_width: u16) -> u16 {
5 let inner_width = terminal_width.saturating_sub(3) as usize; if cursor_pos >= inner_width {
8 (cursor_pos + 1).saturating_sub(inner_width) as u16
10 } else {
11 0
12 }
13}
14
15#[must_use]
17pub fn update_scroll_offset(cursor_pos: usize, current_offset: u16, visible_width: usize) -> u16 {
18 if cursor_pos < current_offset as usize {
20 cursor_pos as u16
21 }
22 else if cursor_pos >= current_offset as usize + visible_width {
24 (cursor_pos + 1).saturating_sub(visible_width) as u16
25 }
26 else {
28 current_offset
29 }
30}
31
32#[must_use]
34pub fn calculate_visible_range(
35 total_items: usize,
36 viewport_start: usize,
37 viewport_size: usize,
38) -> (usize, usize) {
39 let start = viewport_start.min(total_items);
40 let end = (viewport_start + viewport_size).min(total_items);
41 (start, end)
42}
43
44#[must_use]
46pub fn calculate_page_jump(
47 current_pos: usize,
48 page_size: usize,
49 total_items: usize,
50 direction_up: bool,
51) -> usize {
52 if direction_up {
53 current_pos.saturating_sub(page_size)
54 } else {
55 (current_pos + page_size).min(total_items.saturating_sub(1))
56 }
57}
58
59#[must_use]
62pub fn calculate_centered_viewport(
63 target_pos: usize,
64 viewport_size: usize,
65 total_items: usize,
66) -> usize {
67 if total_items <= viewport_size {
68 0
70 } else if target_pos < viewport_size / 2 {
71 0
73 } else if target_pos > total_items.saturating_sub(viewport_size / 2) {
74 total_items.saturating_sub(viewport_size)
76 } else {
77 target_pos.saturating_sub(viewport_size / 2)
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn test_horizontal_scroll() {
88 assert_eq!(calculate_horizontal_scroll(5, 80), 0);
90
91 assert_eq!(calculate_horizontal_scroll(100, 80), 24); }
94
95 #[test]
96 fn test_update_scroll_offset() {
97 assert_eq!(update_scroll_offset(5, 10, 20), 5);
99
100 assert_eq!(update_scroll_offset(15, 10, 20), 10);
102
103 assert_eq!(update_scroll_offset(35, 10, 20), 16); }
106
107 #[test]
108 fn test_visible_range() {
109 assert_eq!(calculate_visible_range(100, 10, 20), (10, 30));
110 assert_eq!(calculate_visible_range(100, 90, 20), (90, 100));
111 assert_eq!(calculate_visible_range(5, 0, 10), (0, 5));
112 }
113
114 #[test]
115 fn test_page_jump() {
116 assert_eq!(calculate_page_jump(50, 10, 100, true), 40);
118 assert_eq!(calculate_page_jump(5, 10, 100, true), 0);
119
120 assert_eq!(calculate_page_jump(50, 10, 100, false), 60);
122 assert_eq!(calculate_page_jump(95, 10, 100, false), 99);
123 }
124
125 #[test]
126 fn test_centered_viewport() {
127 assert_eq!(calculate_centered_viewport(5, 20, 10), 0);
129
130 assert_eq!(calculate_centered_viewport(5, 20, 100), 0);
132
133 assert_eq!(calculate_centered_viewport(95, 20, 100), 80);
135
136 assert_eq!(calculate_centered_viewport(50, 20, 100), 40);
138 }
139}