1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
use std::{error::Error, io};

use crossterm::{event, style, terminal};

use crate::{
    error::ErrorKind, Attribute, Clear, Color, Event, KeyCode, KeyEvent, KeyModifiers, MouseButton,
    MouseEvent,
};

impl From<Attribute> for style::Attribute {
    fn from(attribute: Attribute) -> Self {
        match attribute {
            Attribute::Reset => style::Attribute::Reset,
            Attribute::Bold => style::Attribute::Bold,
            Attribute::BoldItalicOff => style::Attribute::Dim,
            Attribute::Italic => style::Attribute::Italic,
            Attribute::Underlined => style::Attribute::Underlined,
            Attribute::SlowBlink => style::Attribute::SlowBlink,
            Attribute::RapidBlink => style::Attribute::RapidBlink,
            Attribute::Reversed => style::Attribute::Reverse,
            Attribute::Conceal => style::Attribute::Hidden,
            Attribute::Crossed => style::Attribute::CrossedOut,
            Attribute::Fraktur => style::Attribute::Fraktur,
            Attribute::BoldOff => style::Attribute::NoBold,
            Attribute::NormalIntensity => style::Attribute::NormalIntensity,
            Attribute::ItalicOff => style::Attribute::NoItalic,
            Attribute::UnderlinedOff => style::Attribute::NoUnderline,
            Attribute::BlinkOff => style::Attribute::NoBlink,
            Attribute::ReversedOff => style::Attribute::NoReverse,
            Attribute::ConcealOff => style::Attribute::NoHidden,
            Attribute::CrossedOff => style::Attribute::NotCrossedOut,
            Attribute::Framed => style::Attribute::Framed,
            Attribute::__Nonexhaustive => style::Attribute::__Nonexhaustive,
        }
    }
}

impl From<Color> for style::Color {
    fn from(color: Color) -> Self {
        match color {
            Color::Reset => style::Color::Reset,
            Color::Black => style::Color::Black,
            Color::DarkGrey => style::Color::DarkGrey,
            Color::Red => style::Color::Red,
            Color::DarkRed => style::Color::DarkRed,
            Color::Green => style::Color::Green,
            Color::DarkGreen => style::Color::DarkGreen,
            Color::Yellow => style::Color::Yellow,
            Color::DarkYellow => style::Color::DarkYellow,
            Color::Blue => style::Color::Blue,
            Color::DarkBlue => style::Color::DarkBlue,
            Color::Magenta => style::Color::Magenta,
            Color::DarkMagenta => style::Color::DarkMagenta,
            Color::Cyan => style::Color::Cyan,
            Color::DarkCyan => style::Color::DarkCyan,
            Color::White => style::Color::White,
            Color::Grey => style::Color::Grey,
            Color::Rgb(r, g, b) => style::Color::Rgb { r, g, b },
            Color::AnsiValue(val) => style::Color::AnsiValue(val),
        }
    }
}

impl From<Clear> for terminal::ClearType {
    fn from(clear_type: Clear) -> Self {
        match clear_type {
            Clear::All => terminal::ClearType::All,
            Clear::FromCursorDown => terminal::ClearType::FromCursorDown,
            Clear::FromCursorUp => terminal::ClearType::FromCursorUp,
            Clear::CurrentLine => terminal::ClearType::CurrentLine,
            Clear::UntilNewLine => terminal::ClearType::UntilNewLine,
        }
    }
}

impl From<event::MouseButton> for MouseButton {
    fn from(buttons: event::MouseButton) -> Self {
        match buttons {
            event::MouseButton::Left => MouseButton::Left,
            event::MouseButton::Right => MouseButton::Right,
            event::MouseButton::Middle => MouseButton::Middle,
        }
    }
}

impl From<event::MouseEvent> for MouseEvent {
    fn from(event: event::MouseEvent) -> Self {
        match event {
            event::MouseEvent::Down(btn, x, y, modifiers) => {
                MouseEvent::Up(btn.into(), x, y, modifiers.into())
            }
            event::MouseEvent::Up(btn, x, y, modifiers) => {
                MouseEvent::Up(btn.into(), x, y, modifiers.into())
            }
            event::MouseEvent::Drag(btn, x, y, modifiers) => {
                MouseEvent::Drag(btn.into(), x, y, modifiers.into())
            }
            event::MouseEvent::ScrollDown(x, y, modifiers) => {
                MouseEvent::ScrollUp(x, y, modifiers.into())
            }
            event::MouseEvent::ScrollUp(x, y, modifiers) => {
                MouseEvent::ScrollDown(x, y, modifiers.into())
            }
        }
    }
}

impl From<event::KeyModifiers> for KeyModifiers {
    fn from(modifiers: event::KeyModifiers) -> Self {
        let shift = modifiers.contains(event::KeyModifiers::SHIFT);
        let ctrl = modifiers.contains(event::KeyModifiers::CONTROL);
        let alt = modifiers.contains(event::KeyModifiers::ALT);

        let mut modifiers = KeyModifiers::empty();

        if shift {
            modifiers |= KeyModifiers::SHIFT;
        }
        if ctrl {
            modifiers |= KeyModifiers::CONTROL;
        }
        if alt {
            modifiers |= KeyModifiers::ALT;
        }

        modifiers
    }
}

impl From<event::KeyCode> for KeyCode {
    fn from(code: event::KeyCode) -> Self {
        match code {
            event::KeyCode::Backspace => KeyCode::Backspace,
            event::KeyCode::Enter => KeyCode::Enter,
            event::KeyCode::Left => KeyCode::Left,
            event::KeyCode::Right => KeyCode::Right,
            event::KeyCode::Up => KeyCode::Up,
            event::KeyCode::Down => KeyCode::Down,
            event::KeyCode::Home => KeyCode::Home,
            event::KeyCode::End => KeyCode::End,
            event::KeyCode::PageUp => KeyCode::PageUp,
            event::KeyCode::PageDown => KeyCode::PageDown,
            event::KeyCode::Tab => KeyCode::Tab,
            event::KeyCode::BackTab => KeyCode::BackTab,
            event::KeyCode::Delete => KeyCode::Delete,
            event::KeyCode::Insert => KeyCode::Insert,
            event::KeyCode::F(f) => KeyCode::F(f),
            event::KeyCode::Char(c) => KeyCode::Char(c),
            event::KeyCode::Null => KeyCode::Null,
            event::KeyCode::Esc => KeyCode::Esc,
        }
    }
}

impl From<event::KeyEvent> for KeyEvent {
    fn from(event: event::KeyEvent) -> Self {
        KeyEvent {
            code: KeyCode::from(event.code),
            modifiers: KeyModifiers::from(event.modifiers),
        }
    }
}

impl From<event::Event> for Event {
    fn from(event: event::Event) -> Self {
        match event {
            event::Event::Key(key) => Event::Key(KeyEvent::from(key)),
            event::Event::Mouse(mouse) => Event::Mouse(MouseEvent::from(mouse)),
            event::Event::Resize(_x, _y) => Event::Resize,
        }
    }
}

impl From<crossterm::ErrorKind> for ErrorKind {
    fn from(error: crossterm::ErrorKind) -> Self {
        match error {
            crossterm::ErrorKind::IoError(e) => ErrorKind::IoError(e),
            e => ErrorKind::IoError(io::Error::new(io::ErrorKind::Other, e.description())),
        }
    }
}