Skip to main content

r_matrix/
config.rs

1use clap::{ArgAction, Parser};
2
3use super::MatrixColor;
4
5#[derive(Debug, Parser)]
6#[command(
7    name = "rmatrix",
8    about = "Shows a scrolling 'Matrix' like screen in your terminal"
9)]
10struct Opt {
11    #[arg(short = 'b', action = ArgAction::Count)]
12    /// Bold characters on
13    bold: u8,
14
15    #[arg(short = 'l', long = "console")]
16    /// Linux mode (use matrix console font)
17    console: bool,
18
19    #[arg(short = 'o', long = "oldstyle")]
20    /// Use old-style scrolling
21    oldstyle: bool,
22
23    #[arg(short = 's', long = "screensaver")]
24    /// "Screensaver" mode, exits on first keystroke
25    screensaver: bool,
26
27    #[arg(short = 'x', long = "xwindow")]
28    /// X window mode, use if your xterm is using mtx.pcf
29    xwindow: bool,
30
31    #[arg(
32        short = 'u',
33        long = "update",
34        default_value = "4",
35        value_parser = validate_update
36    )]
37    /// Screen update delay
38    update: usize,
39
40    #[arg(
41        short = 'C',
42        long = "colour",
43        default_value = "green",
44        value_parser = ["green", "red", "blue", "white", "yellow", "cyan", "magenta", "black"]
45    )]
46    colour: String,
47
48    #[arg(short = 'r', long = "rainbow")]
49    /// Rainbow mode
50    rainbow: bool,
51}
52
53fn validate_update(n: &str) -> Result<usize, &'static str> {
54    if let Ok(n) = n.parse::<usize>()
55        && n <= 10
56    {
57        return Ok(n);
58    }
59    Err("must be a number between 1 and 10")
60}
61
62/// The global state object
63pub struct Config {
64    pub bold: isize,
65    pub console: bool,
66    pub oldstyle: bool,
67    pub screensaver: bool,
68    pub xwindow: bool,
69    pub update: usize,
70    pub colour: MatrixColor,
71    pub rainbow: bool,
72    pub pause: bool,
73}
74
75impl Default for Config {
76    /// Get the new config object based on command line arguments
77    fn default() -> Self {
78        let opt = Opt::parse();
79
80        let colour = match opt.colour.as_ref() {
81            "green" => MatrixColor::Green,
82            "red" => MatrixColor::Red,
83            "blue" => MatrixColor::Blue,
84            "white" => MatrixColor::White,
85            "yellow" => MatrixColor::Yellow,
86            "cyan" => MatrixColor::Cyan,
87            "magenta" => MatrixColor::Magenta,
88            "black" => MatrixColor::Black,
89            _ => unreachable!(),
90        };
91
92        Config {
93            bold: opt.bold as isize,
94            console: opt.console,
95            oldstyle: opt.oldstyle,
96            screensaver: opt.screensaver,
97            xwindow: opt.xwindow,
98            update: opt.update,
99            rainbow: opt.rainbow,
100            colour,
101            pause: false,
102        }
103    }
104}
105
106impl Config {
107    /// Update the config based on any keypresses
108    pub fn handle_keypress(&mut self, keypress: char) -> bool {
109        // Exit if in screensaver mode
110        if self.screensaver {
111            return true;
112        }
113
114        match keypress {
115            'q' => return true,
116            'b' => self.bold = 1,
117            'B' => self.bold = 2,
118            'n' => self.bold = 0,
119            '!' => {
120                self.colour = MatrixColor::Red;
121                self.rainbow = false;
122            }
123            '@' => {
124                self.colour = MatrixColor::Green;
125                self.rainbow = false;
126            }
127            '#' => {
128                self.colour = MatrixColor::Yellow;
129                self.rainbow = false;
130            }
131            '$' => {
132                self.colour = MatrixColor::Blue;
133                self.rainbow = false;
134            }
135            '%' => {
136                self.colour = MatrixColor::Magenta;
137                self.rainbow = false;
138            }
139            'r' => {
140                self.rainbow = true;
141            }
142            '^' => {
143                self.colour = MatrixColor::Cyan;
144                self.rainbow = false;
145            }
146            '&' => {
147                self.colour = MatrixColor::White;
148                self.rainbow = false;
149            }
150            'p' | 'P' => self.pause = !self.pause,
151            '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' => {
152                self.update = keypress as usize - 48 // Sneaky way to avoid parsing
153            }
154            _ => {}
155        }
156        false
157    }
158}