sql_cli/handlers/
yank.rs

1use crate::app_state_container::AppStateContainer;
2use crate::buffer::BufferAPI;
3use crate::ui::input::actions::{Action, YankTarget};
4use crate::yank_manager::YankManager;
5use anyhow::Result;
6use tracing::debug;
7
8pub struct YankHandler;
9
10impl YankHandler {
11    pub fn handle_yank_action(
12        action: &Action,
13        buffer: &dyn BufferAPI,
14        state_container: &AppStateContainer,
15    ) -> Result<Option<String>> {
16        match action {
17            Action::Yank(target) => {
18                let result = Self::execute_yank(target, buffer, state_container)?;
19                Ok(Some(result))
20            }
21            _ => Ok(None),
22        }
23    }
24
25    fn execute_yank(
26        target: &YankTarget,
27        buffer: &dyn BufferAPI,
28        state_container: &AppStateContainer,
29    ) -> Result<String> {
30        match target {
31            YankTarget::Cell => Self::yank_cell(buffer, state_container),
32            YankTarget::Row => Self::yank_row(buffer, state_container),
33            YankTarget::Column => Self::yank_column(buffer, state_container),
34            YankTarget::All => Self::yank_all(buffer, state_container),
35            YankTarget::Query => Self::yank_query(buffer, state_container),
36        }
37    }
38
39    fn yank_cell(buffer: &dyn BufferAPI, state_container: &AppStateContainer) -> Result<String> {
40        debug!("yank_cell called");
41
42        // Use buffer.get_selected_row() to get the actual table row selection
43        if let Some(selected_row) = buffer.get_selected_row() {
44            let column = buffer.get_current_column();
45            debug!("Yanking cell at row={}, column={}", selected_row, column);
46
47            let result = YankManager::yank_cell(buffer, state_container, selected_row, column)?;
48            let message = format!("Yanked cell: {}", result.full_value);
49            Ok(message)
50        } else {
51            debug!("No row selected for yank");
52            Ok("No row selected".to_string())
53        }
54    }
55
56    fn yank_row(buffer: &dyn BufferAPI, state_container: &AppStateContainer) -> Result<String> {
57        // Use buffer.get_selected_row() to get the actual table row selection
58        if let Some(selected_row) = buffer.get_selected_row() {
59            let result = YankManager::yank_row(buffer, state_container, selected_row)?;
60            let message = format!("Yanked {}", result.description);
61            Ok(message)
62        } else {
63            Ok("No row selected".to_string())
64        }
65    }
66
67    fn yank_column(buffer: &dyn BufferAPI, state_container: &AppStateContainer) -> Result<String> {
68        let column = buffer.get_current_column();
69        let result = YankManager::yank_column(buffer, state_container, column)?;
70        let message = format!("Yanked {}", result.description);
71        Ok(message)
72    }
73
74    fn yank_all(buffer: &dyn BufferAPI, state_container: &AppStateContainer) -> Result<String> {
75        let result = YankManager::yank_all(buffer, state_container)?;
76        let message = format!("Yanked {}: {}", result.description, result.preview);
77        Ok(message)
78    }
79
80    fn yank_query(buffer: &dyn BufferAPI, state_container: &AppStateContainer) -> Result<String> {
81        let query = buffer.get_input_text();
82
83        if query.trim().is_empty() {
84            return Ok("No query to yank".to_string());
85        }
86
87        // Just write to clipboard - AppStateContainer handles the rest
88        state_container.write_to_clipboard(&query)?;
89
90        let char_count = query.len();
91        let status_msg = format!("Yanked SQL ({char_count} chars)");
92        debug!("Yanking query: {}", &status_msg);
93
94        Ok(status_msg)
95    }
96
97    pub fn handle_yank_as_test_case(
98        buffer: &dyn BufferAPI,
99        state_container: &AppStateContainer,
100    ) -> Result<String> {
101        use crate::utils::debug_info::DebugInfo;
102
103        let test_case = DebugInfo::generate_test_case(buffer);
104        state_container.yank_test_case(test_case.clone())?;
105
106        let message = format!(
107            "Copied complete test case to clipboard ({} lines)",
108            test_case.lines().count()
109        );
110        Ok(message)
111    }
112
113    pub fn handle_yank_debug_context(
114        buffer: &dyn BufferAPI,
115        state_container: &AppStateContainer,
116    ) -> Result<String> {
117        use crate::utils::debug_info::DebugInfo;
118
119        let debug_context = DebugInfo::generate_debug_context(buffer);
120        state_container.yank_debug_context(debug_context.clone())?;
121
122        let message = format!(
123            "Copied debug context to clipboard ({} lines)",
124            debug_context.lines().count()
125        );
126        Ok(message)
127    }
128}