1use crate::api_client::ApiClient;
2use crate::cache::QueryCache;
3use crate::config::config::Config;
4use crate::history::CommandHistory;
5use crate::hybrid_parser::HybridParser;
6use crate::parser::SqlParser;
7use crate::sql_highlighter::SqlHighlighter;
8
9pub struct GlobalState {
12 pub api_client: ApiClient,
14 pub sql_parser: SqlParser,
15 pub hybrid_parser: HybridParser,
16 pub sql_highlighter: SqlHighlighter,
17 pub config: Config,
18 pub command_history: CommandHistory,
19 pub query_cache: Option<QueryCache>,
20
21 pub show_help: bool,
23 pub help_scroll: u16,
24 pub debug_text: String,
25 pub debug_scroll: u16,
26 pub input_scroll_offset: u16, pub selection_mode: SelectionMode,
30 pub yank_mode: Option<char>,
31 pub last_yanked: Option<(String, String)>, pub completion_state: CompletionState,
35 pub history_state: HistoryState,
36
37 pub jump_to_row_input: String,
39
40 pub cache_mode: bool,
42}
43
44#[derive(Clone, PartialEq)]
45pub enum SelectionMode {
46 Row,
47 Cell,
48}
49
50#[derive(Clone)]
51pub struct CompletionState {
52 pub suggestions: Vec<String>,
53 pub current_index: usize,
54 pub last_query: String,
55 pub last_cursor_pos: usize,
56}
57
58#[derive(Clone)]
59pub struct HistoryState {
60 pub search_query: String,
61 pub matches: Vec<(usize, String)>, pub selected_index: usize,
63}
64
65impl GlobalState {
66 #[must_use]
67 pub fn new(api_url: &str, config: Config) -> Self {
68 Self {
69 api_client: ApiClient::new(api_url),
70 sql_parser: SqlParser::new(),
71 hybrid_parser: HybridParser::new(),
72 sql_highlighter: SqlHighlighter::new(),
73 command_history: CommandHistory::new().unwrap_or_default(),
74 query_cache: None,
75 config,
76
77 show_help: false,
78 help_scroll: 0,
79 debug_text: String::new(),
80 debug_scroll: 0,
81 input_scroll_offset: 0,
82
83 selection_mode: SelectionMode::Row,
84 yank_mode: None,
85 last_yanked: None,
86
87 completion_state: CompletionState {
88 suggestions: Vec::new(),
89 current_index: 0,
90 last_query: String::new(),
91 last_cursor_pos: 0,
92 },
93
94 history_state: HistoryState {
95 search_query: String::new(),
96 matches: Vec::new(),
97 selected_index: 0,
98 },
99
100 jump_to_row_input: String::new(),
101
102 cache_mode: false,
103 }
104 }
105
106 pub fn toggle_help(&mut self) {
108 self.show_help = !self.show_help;
109 if self.show_help {
110 self.help_scroll = 0; }
112 }
113
114 pub fn clear_debug(&mut self) {
116 self.debug_text.clear();
117 self.debug_scroll = 0;
118 }
119
120 pub fn add_debug_line(&mut self, line: String) {
122 if !self.debug_text.is_empty() {
123 self.debug_text.push('\n');
124 }
125 self.debug_text.push_str(&line);
126 }
127
128 pub fn toggle_selection_mode(&mut self) {
130 self.selection_mode = match self.selection_mode {
131 SelectionMode::Row => SelectionMode::Cell,
132 SelectionMode::Cell => SelectionMode::Row,
133 };
134 }
135
136 pub fn is_cell_mode(&self) -> bool {
138 matches!(self.selection_mode, SelectionMode::Cell)
139 }
140
141 pub fn toggle_cache_mode(&mut self) {
143 self.cache_mode = !self.cache_mode;
144 }
145
146 pub fn init_cache(&mut self, _cache_dir: Option<std::path::PathBuf>) {
148 if self.query_cache.is_none() {
149 self.query_cache = QueryCache::new().ok();
150 }
151 }
152}