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 pub fn new(api_url: &str, config: Config) -> Self {
67 Self {
68 api_client: ApiClient::new(api_url),
69 sql_parser: SqlParser::new(),
70 hybrid_parser: HybridParser::new(),
71 sql_highlighter: SqlHighlighter::new(),
72 command_history: CommandHistory::new().unwrap_or_default(),
73 query_cache: None,
74 config,
75
76 show_help: false,
77 help_scroll: 0,
78 debug_text: String::new(),
79 debug_scroll: 0,
80 input_scroll_offset: 0,
81
82 selection_mode: SelectionMode::Row,
83 yank_mode: None,
84 last_yanked: None,
85
86 completion_state: CompletionState {
87 suggestions: Vec::new(),
88 current_index: 0,
89 last_query: String::new(),
90 last_cursor_pos: 0,
91 },
92
93 history_state: HistoryState {
94 search_query: String::new(),
95 matches: Vec::new(),
96 selected_index: 0,
97 },
98
99 jump_to_row_input: String::new(),
100
101 cache_mode: false,
102 }
103 }
104
105 pub fn toggle_help(&mut self) {
107 self.show_help = !self.show_help;
108 if self.show_help {
109 self.help_scroll = 0; }
111 }
112
113 pub fn clear_debug(&mut self) {
115 self.debug_text.clear();
116 self.debug_scroll = 0;
117 }
118
119 pub fn add_debug_line(&mut self, line: String) {
121 if !self.debug_text.is_empty() {
122 self.debug_text.push('\n');
123 }
124 self.debug_text.push_str(&line);
125 }
126
127 pub fn toggle_selection_mode(&mut self) {
129 self.selection_mode = match self.selection_mode {
130 SelectionMode::Row => SelectionMode::Cell,
131 SelectionMode::Cell => SelectionMode::Row,
132 };
133 }
134
135 pub fn is_cell_mode(&self) -> bool {
137 matches!(self.selection_mode, SelectionMode::Cell)
138 }
139
140 pub fn toggle_cache_mode(&mut self) {
142 self.cache_mode = !self.cache_mode;
143 }
144
145 pub fn init_cache(&mut self, _cache_dir: Option<std::path::PathBuf>) {
147 if self.query_cache.is_none() {
148 self.query_cache = QueryCache::new().ok();
149 }
150 }
151}