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
mod checkbox_list;
mod list;
mod term_data;

#[cfg(windows)]
::windows::include_bindings!();

pub use checkbox_list::CheckboxList as CheckboxList;
pub use list::List as List;

pub enum InquiryMessage {
    CloseRequested,
    FlushLockErr,
    TermDisableRawErr,
    TermEnableRawErr,
}

pub enum Keys {
    A,
    Up,
    Down,
    Left,
    Right,
    CtrlC,
    CtrlZ,
    Escape,
    Enter,
    Unhandled([u8;4]),
}

impl From<Stdin> for Keys {
    fn from(mut std_in: Stdin) -> Self {
        let mut data = [0, 0, 0, 0];
        let bytes_read = match std_in.read(&mut data) {
            Ok(bytes) => bytes,
            Err(error) =>
                panic!("There was an issue when reading bytes from std input \
                       stream. {}", error)
        };

        match data[0] {
            3 => Self::CtrlC,
            26 => Self::CtrlZ,
            #[cfg(windows)]
            13 => Self::Enter,
            #[cfg(unix)]
            10 => Self::Enter,
            27 => {
                if bytes_read == 0 {
                    return Self::Escape
                }

                match data[1] {
                    91 => match data[2] {
                        65 => Self::Up,
                        66 => Self::Down,
                        67 => Self::Right,
                        68 => Self::Left,
                        _ =>  Self::Unhandled(data)
                    },
                    _ => Self::Unhandled(data)
                }

            },
            97 => Self::A,
            _ => Self::Unhandled(data)
        }
    }
}

use std::io::{ Read, Stdin };