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
use clap::{self, App, Arg, AppSettings};
use glutin::get_primary_monitor;
use std::str::{self, FromStr};
use std::path::PathBuf;
use std::env::home_dir;
use regex::Regex;
use std::fs;
lazy_static! {
static ref SIZE_ARG_RGX: Regex = Regex::new(r"(\d+)x(\d+)").unwrap();
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct Options {
pub config_dir: (String, PathBuf),
pub desktop_size: (u32, u32),
}
impl Options {
pub fn parse() -> Options {
let detected_resolution_default = {
let (w, h) = get_primary_monitor().get_dimensions();
format!("{}x{}", w, h)
};
let matches = App::new("poke-a-mango")
.version(crate_version!())
.author(crate_authors!())
.setting(AppSettings::ColoredHelp)
.about("What all the kool kidz are playing these days")
.arg(Arg::from_usage("-c --config-dir=[CONFIG_DIR] 'Directory containing configuration. Default: $HOME/.poke-a-mango'")
.validator(Options::config_dir_validator))
.arg(Arg::from_usage("-d --desktop-size=[DESKTOP_SIZE] 'The desktop's resolution'")
.default_value(&detected_resolution_default)
.validator(Options::size_validator))
.get_matches();
Options {
config_dir: match matches.value_of("config-dir") {
Some(dirs) => (dirs.to_string(), fs::canonicalize(dirs).unwrap()),
None => {
match home_dir() {
Some(mut hd) => {
hd = hd.canonicalize().unwrap();
hd.push(".poke-a-mango");
fs::create_dir_all(&hd).unwrap();
("$HOME/.poke-a-mango".to_string(), hd)
}
None => {
clap::Error {
message: "Couldn't automatically get home directory, please specify configuration directory with the -c option".to_string(),
kind: clap::ErrorKind::MissingRequiredArgument,
info: None,
}
.exit()
}
}
}
},
desktop_size: Options::parse_size(matches.value_of("desktop-size").unwrap()).unwrap(),
}
}
fn parse_size(s: &str) -> Option<(u32, u32)> {
SIZE_ARG_RGX.captures(s).map(|c| (u32::from_str(c.at(1).unwrap()).unwrap(), u32::from_str(c.at(2).unwrap()).unwrap()))
}
fn config_dir_validator(s: String) -> Result<(), String> {
fs::canonicalize(&s).map(|_| ()).map_err(|_| format!("Configuration directory \"{}\" not found", s))
}
fn size_validator(s: String) -> Result<(), String> {
match Options::parse_size(&s) {
None => Err(format!("\"{}\" is not a valid size (in format \"NNNxMMM\")", s)),
Some((0, _)) | Some((_, 0)) => Err("Can't resize image to size 0".to_string()),
Some(_) => Ok(()),
}
}
}