Skip to main content

hyprshell_config_lib/
check.rs

1use crate::Config;
2use anyhow::bail;
3
4pub fn check(config: &Config) -> anyhow::Result<()> {
5    if config
6        .windows
7        .as_ref()
8        .is_some_and(|w| w.scale >= 15f64 || w.scale <= 0f64)
9    {
10        bail!("Scale factor must be less than 15 and greater than 0");
11    }
12
13    if config
14        .windows
15        .as_ref()
16        .and_then(|w| w.overview.as_ref())
17        .is_some_and(|o| matches!(&*o.key, "super" | "alt" | "control" | "ctrl"))
18    {
19        bail!(
20            "If a modifier key is used to open it must include _l or _r at the end. (e.g. super_l, alt_r, etc)\nctrl_l / _r is NOT a valid modifier key, only control_l / _r is"
21        );
22    }
23
24    if let Some(l) = &config
25        .windows
26        .as_ref()
27        .and_then(|w| w.overview.as_ref().map(|o| &o.launcher))
28    {
29        if let Some(dt) = &l.default_terminal
30            && dt.is_empty()
31        {
32            bail!("Default terminal command cannot be empty");
33        }
34
35        let mut used: Vec<char> = vec![];
36        for engine in l
37            .plugins
38            .websearch
39            .as_ref()
40            .map_or(&vec![], |ws| &ws.engines)
41        {
42            if engine.url.is_empty() {
43                bail!("Search engine url cannot be empty");
44            }
45            if engine.name.is_empty() {
46                bail!("Search engine name cannot be empty");
47            }
48            if used.contains(&engine.key) {
49                bail!("Duplicate search engine key: {}", engine.key);
50            }
51            used.push(engine.key);
52        }
53        if l.plugins.calc.is_some() {
54            #[cfg(not(feature = "launcher_calc_plugin"))]
55            {
56                bail!("Calc Plugin enabled but not compiled in, please enable the calc feature");
57            }
58        }
59    }
60
61    Ok(())
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67    use crate::structs::*;
68
69    fn full() -> Config {
70        Config {
71            windows: Some(Windows {
72                overview: Some(Overview::default()),
73                switch: Some(Switch::default()),
74                ..Default::default()
75            }),
76            ..Default::default()
77        }
78    }
79
80    #[test_log::test]
81    #[test_log(default_log_filter = "trace")]
82    fn test_valid_config() {
83        let config = full();
84        assert!(check(&config).is_ok());
85    }
86
87    #[test_log::test]
88    #[test_log(default_log_filter = "trace")]
89    fn test_invalid_scale() {
90        let mut config = full();
91        config
92            .windows
93            .as_mut()
94            .expect("config option missing")
95            .scale = 20.0;
96        assert!(check(&config).is_err());
97        config
98            .windows
99            .as_mut()
100            .expect("config option missing")
101            .scale = 0.0;
102        assert!(check(&config).is_err());
103    }
104
105    #[test_log::test]
106    #[test_log(default_log_filter = "trace")]
107    fn test_invalid_key() {
108        let mut config = full();
109        let overview = config
110            .windows
111            .as_mut()
112            .expect("config option missing")
113            .overview
114            .as_mut()
115            .expect("config option missing");
116        overview.key = Box::from("super");
117        assert!(check(&config).is_err());
118    }
119
120    #[test_log::test]
121    #[test_log(default_log_filter = "trace")]
122    fn test_duplicate_engine_key() {
123        let mut config = full();
124        let launcher = &mut config
125            .windows
126            .as_mut()
127            .expect("config option missing")
128            .overview
129            .as_mut()
130            .expect("config option missing")
131            .launcher;
132        if let Some(ws) = launcher.plugins.websearch.as_mut() {
133            ws.engines.push(SearchEngine {
134                key: 'g',
135                name: Box::from("Google2"),
136                url: Box::from("https://google2.com"),
137            });
138        }
139        assert!(check(&config).is_err());
140    }
141
142    #[test_log::test]
143    #[test_log(default_log_filter = "trace")]
144    fn test_empty_engine_url() {
145        let mut config = full();
146        let launcher = &mut config
147            .windows
148            .as_mut()
149            .expect("config option missing")
150            .overview
151            .as_mut()
152            .expect("config option missing")
153            .launcher;
154        if let Some(ws) = launcher.plugins.websearch.as_mut() {
155            ws.engines[0].url = Box::from("");
156        }
157        assert!(check(&config).is_err());
158    }
159
160    #[test_log::test]
161    #[test_log(default_log_filter = "trace")]
162    fn test_empty_engine_name() {
163        let mut config = full();
164        let launcher = &mut config
165            .windows
166            .as_mut()
167            .expect("config option missing")
168            .overview
169            .as_mut()
170            .expect("config option missing")
171            .launcher;
172        if let Some(ws) = launcher.plugins.websearch.as_mut() {
173            ws.engines[0].name = Box::from("");
174        }
175        assert!(check(&config).is_err());
176    }
177
178    #[test_log::test]
179    #[test_log(default_log_filter = "trace")]
180    fn test_empty_terminal() {
181        let mut config = full();
182        let launcher = &mut config
183            .windows
184            .as_mut()
185            .expect("config option missing")
186            .overview
187            .as_mut()
188            .expect("config option missing")
189            .launcher;
190        launcher.default_terminal = Some(Box::from(""));
191        assert!(check(&config).is_err());
192    }
193}