tastty-core 0.1.0

Sans-IO core of the tastty terminal session library: VT parser, screen buffer, and byte encoders.
use super::{CursorStyle, Screen, TerminalMode};

// tui-term trait impls
impl tui_term::widget::Screen for Screen {
    type C = crate::cell::Cell;

    fn cell(&self, row: u16, col: u16) -> Option<&Self::C> {
        self.cell(row, col)
    }

    fn hide_cursor(&self) -> bool {
        self.mode(TerminalMode::HideCursor)
    }

    fn cursor_position(&self) -> (u16, u16) {
        let pos = self.cursor();
        (pos.row, pos.col)
    }

    fn cursor_shape(&self) -> tui_term::widget::CursorShape {
        match self.cursor_style() {
            CursorStyle::Default => tui_term::widget::CursorShape::Default,
            CursorStyle::BlinkingBlock => tui_term::widget::CursorShape::BlinkingBlock,
            CursorStyle::SteadyBlock => tui_term::widget::CursorShape::SteadyBlock,
            CursorStyle::BlinkingUnderline => tui_term::widget::CursorShape::BlinkingUnderline,
            CursorStyle::SteadyUnderline => tui_term::widget::CursorShape::SteadyUnderline,
            CursorStyle::BlinkingBar => tui_term::widget::CursorShape::BlinkingBar,
            CursorStyle::SteadyBar => tui_term::widget::CursorShape::SteadyBar,
        }
    }
}

impl tui_term::widget::Cell for crate::cell::Cell {
    fn has_contents(&self) -> bool {
        self.has_contents()
    }

    fn apply(&self, buf_cell: &mut ratatui_core::buffer::Cell) {
        use ratatui_core::style::{Modifier, Style};

        if self.has_contents() {
            buf_cell.set_symbol(self.contents());
        }
        let attrs = self.attrs();
        let fg = color_to_ratatui(attrs.fg_color);
        let bg = color_to_ratatui(attrs.bg_color);
        let mut style = Style::reset();
        if attrs.bold() {
            style = style.add_modifier(Modifier::BOLD);
        }
        if attrs.italic() {
            style = style.add_modifier(Modifier::ITALIC);
        }
        if attrs.underline() {
            // ratatui-core 0.1 only has UNDERLINED; map all variants to it.
            // The actual style is preserved in the cell for when ratatui
            // adds DOUBLE_UNDERLINED / UNDERCURLED / UNDERDOTTED / UNDERDASHED.
            style = style.add_modifier(Modifier::UNDERLINED);
        }
        let ul_color = color_to_ratatui(attrs.underline_color);
        if ul_color != ratatui_core::style::Color::Reset {
            style.underline_color = Some(ul_color);
        }
        if attrs.inverse() {
            style = style.add_modifier(Modifier::REVERSED);
        }
        if attrs.dim() {
            style = style.add_modifier(Modifier::DIM);
        }
        if attrs.strikethrough() {
            style = style.add_modifier(Modifier::CROSSED_OUT);
        }
        if attrs.hidden() {
            style = style.add_modifier(Modifier::HIDDEN);
        }
        if attrs.blink() {
            style = style.add_modifier(Modifier::SLOW_BLINK);
        }
        buf_cell.set_style(style.fg(fg).bg(bg));
    }
}

fn color_to_ratatui(color: crate::attrs::Color) -> ratatui_core::style::Color {
    match color {
        crate::attrs::Color::Default => ratatui_core::style::Color::Reset,
        crate::attrs::Color::Index(i) => ratatui_core::style::Color::Indexed(i),
        crate::attrs::Color::Rgb(r, g, b) => ratatui_core::style::Color::Rgb(r, g, b),
    }
}