tabiew 0.13.1

A lightweight TUI application to view and query tabular data files, such as CSV, TSV, and parquet.
use std::fmt::Display;

use crossterm::event::{KeyCode, KeyModifiers};
use strum::IntoEnumIterator;
use strum_macros::{EnumIter, IntoStaticStr};

use crate::{
    handler::message::Message,
    misc::{config::config, type_ext::UnwrapOrEnqueueError},
    tui::{component::Component, pickers::search_picker::SearchPicker},
};

#[derive(Debug)]
pub struct CommandPalette {
    picker: SearchPicker<Command>,
}

impl Default for CommandPalette {
    fn default() -> Self {
        Self {
            picker: SearchPicker::new(Command::all()),
        }
    }
}

impl Component for CommandPalette {
    fn render(
        &mut self,
        area: ratatui::prelude::Rect,
        buf: &mut ratatui::prelude::Buffer,
        focus_state: crate::tui::component::FocusState,
    ) {
        self.picker.render(area, buf, focus_state);
    }

    fn handle(&mut self, event: crossterm::event::KeyEvent) -> bool {
        if self.picker.handle(event) {
            match self.picker.text() {
                "s " => {
                    Message::AppDismissOverlay.enqueue();
                    Message::PaneShowInlineSelect.enqueue();
                }
                "o " => {
                    Message::AppDismissOverlay.enqueue();
                    Message::PaneShowInlineOrder.enqueue();
                }
                "f " => {
                    Message::AppDismissOverlay.enqueue();
                    Message::PaneShowInlineFilter.enqueue();
                }
                "q " => {
                    Message::AppDismissOverlay.enqueue();
                    Message::AppShowSqlQuery.enqueue();
                }
                _ => (),
            }
            true
        } else {
            match (event.code, event.modifiers) {
                (KeyCode::Enter, KeyModifiers::NONE) => {
                    Message::AppDismissOverlay.enqueue();
                    if let Some(item) = self.picker.selected_item() {
                        match item {
                            Command::Cast => Message::PaneShowColumnCaster.enqueue(),
                            Command::Info => Message::PaneShowTableInfo.enqueue(),
                            Command::Export => Message::PaneShowExporter.enqueue(),
                            Command::Filter => Message::PaneShowInlineFilter.enqueue(),
                            Command::Histogram => Message::PaneShowHistogramBuilder.enqueue(),
                            Command::Import => Message::AppShowImporter.enqueue(),
                            Command::Order => Message::PaneShowInlineOrder.enqueue(),
                            Command::Query => Message::AppShowSqlQuery.enqueue(),
                            Command::Quit => Message::Quit.enqueue(),
                            Command::Register => Message::PaneShowTableRegisterer.enqueue(),
                            Command::ScatterPlot => Message::PaneShowScatterPlotBuilder.enqueue(),
                            Command::Schema => Message::AppShowSchema.enqueue(),
                            Command::Select => Message::PaneShowInlineSelect.enqueue(),
                            Command::Sort => Message::PaneShowInlineOrder.enqueue(),
                            Command::ThemeSelector => Message::AppShowThemeSelector.enqueue(),
                            Command::ToggleBorders => {
                                config().toggle_show_table_borders();
                                config().store().unwrap_or_enqueue_error();
                            }
                            Command::ToggleRowNumbers => {
                                config().toggle_show_table_row_numbers();
                                config().store().unwrap_or_enqueue_error();
                            }
                            Command::FuzzySearch => Message::PaneShowFuzzySearch.enqueue(),
                            Command::Search => Message::PaneShowSearch.enqueue(),
                            Command::Edit => Message::PaneEditInExternalEditor.enqueue(),
                            Command::ReloadConfig => Message::AppReloadConfig.enqueue(),
                        }
                    }
                    true
                }
                (KeyCode::Esc, KeyModifiers::NONE) => {
                    Message::AppDismissOverlay.enqueue();
                    true
                }
                _ => false,
            }
        }
    }
}

#[derive(Debug, Clone, Copy, EnumIter, IntoStaticStr)]
enum Command {
    Cast,
    Edit,
    Export,
    Filter,
    FuzzySearch,
    Histogram,
    Import,
    Info,
    Order,
    Query,
    Quit,
    Register,
    ReloadConfig,
    ScatterPlot,
    Search,
    Schema,
    Select,
    Sort,
    ThemeSelector,
    ToggleBorders,
    ToggleRowNumbers,
}

impl Command {
    fn all() -> Vec<Command> {
        Command::iter().collect()
    }
}

impl Display for Command {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", Into::<&str>::into(self))
    }
}