-
Notifications
You must be signed in to change notification settings - Fork 24
/
config.rs
73 lines (62 loc) · 1.84 KB
/
config.rs
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
use crate::{Error, Result};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
pub static CONFIG: Lazy<Config> = Lazy::new(Config::load);
#[derive(Serialize, Deserialize)]
#[serde(default)]
pub struct Config {
pub enable_selector: bool,
pub selector: String,
pub terminal_emulator: String,
}
impl Default for Config {
fn default() -> Self {
// This seems repetitive but serde does not uses Default
Config {
enable_selector: false,
selector: std::env::var("TERMINAL").unwrap_or("xterm -e".into()),
terminal_emulator: "rofi -dmenu -p 'Open With: '".into(),
}
}
}
impl Config {
pub fn load() -> Self {
confy::load("handlr").unwrap()
}
pub fn select<O: Iterator<Item = String>>(
&self,
mut opts: O,
) -> Result<String> {
use itertools::Itertools;
use std::{
io::prelude::*,
process::{Command, Stdio},
};
let process = {
let mut split = shlex::split(&self.selector).unwrap();
let (cmd, args) = (split.remove(0), split);
Command::new(cmd)
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?
};
let output = {
process
.stdin
.ok_or(Error::Selector(self.selector.clone()))?
.write_all(opts.join("\n").as_bytes())?;
let mut output = String::with_capacity(24);
process
.stdout
.ok_or(Error::Selector(self.selector.clone()))?
.read_to_string(&mut output)?;
output.trim_end().to_owned()
};
if output.is_empty() {
Err(Error::Cancelled)
} else {
Ok(output)
}
}
}