config: Make YAML/JSON modular and optional (#21)
This commit is contained in:
committed by
Kenny Levinsen
parent
c02937d8b6
commit
c695288d1e
+8
-4
@@ -8,12 +8,15 @@ edition = "2018"
|
||||
lto = "fat"
|
||||
|
||||
[features]
|
||||
default = ["alsa-widget", "pulseaudio-widget"]
|
||||
default = ["alsa-widget", "pulseaudio-widget", "yaml-cfg", "json-cfg"]
|
||||
damage_debug = []
|
||||
|
||||
yaml-cfg = ["serde_yaml"]
|
||||
json-cfg = ["serde_json"]
|
||||
|
||||
alsa-widget = ["alsa"]
|
||||
pulseaudio-widget = ["libpulse-binding"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
smithay-client-toolkit = "0.6.4"
|
||||
byteorder = "1.3"
|
||||
@@ -30,9 +33,10 @@ lazy_static = "1.4"
|
||||
rcalc_lib = { version = "0.9" }
|
||||
rust-ini = "0.13"
|
||||
shlex = "0.1"
|
||||
serde_json = "1.0"
|
||||
serde_yaml = "0.8"
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
serde_yaml = { version = "0.8", optional = true }
|
||||
|
||||
libpulse-binding = { version = "2.11", optional = true }
|
||||
alsa = { version = "0.3.0", optional = true }
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use std::io::BufRead;
|
||||
|
||||
pub enum ConfigFmt {
|
||||
#[cfg(feature = "yaml-cfg")]
|
||||
Yaml,
|
||||
#[cfg(feature = "json-cfg")]
|
||||
Json,
|
||||
}
|
||||
|
||||
pub const CONFIG_NAMES: &'static [&'static str] = &[
|
||||
#[cfg(feature = "yaml-cfg")]
|
||||
"config.yaml",
|
||||
#[cfg(feature = "json-cfg")]
|
||||
"config.json",
|
||||
];
|
||||
|
||||
impl ConfigFmt {
|
||||
#[inline]
|
||||
pub fn new(ext: &str) -> Option<Self> {
|
||||
match ext {
|
||||
#[cfg(feature = "yaml-cfg")]
|
||||
"yaml" => Some(ConfigFmt::Yaml),
|
||||
#[cfg(feature = "json-cfg")]
|
||||
"json" => Some(ConfigFmt::Json),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn from_reader<B: BufRead, T: DeserializeOwned>(&self, r: B) -> T {
|
||||
match self {
|
||||
#[cfg(feature = "yaml-cfg")]
|
||||
ConfigFmt::Yaml => serde_yaml::from_reader(r).unwrap(),
|
||||
#[cfg(feature = "json-cfg")]
|
||||
ConfigFmt::Json => serde_json::from_reader(r).unwrap(),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn to_string<T: Serialize + ?Sized>(&self, src: &T) -> String {
|
||||
match self {
|
||||
#[cfg(feature = "yaml-cfg")]
|
||||
ConfigFmt::Yaml => serde_yaml::to_string(&src).unwrap(),
|
||||
#[cfg(feature = "json-cfg")]
|
||||
ConfigFmt::Json => serde_json::to_string_pretty(&src).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ConfigFmt {
|
||||
fn default() -> Self {
|
||||
// attributes require curly braces to work
|
||||
#[cfg(feature = "yaml-cfg")]
|
||||
{
|
||||
ConfigFmt::Yaml
|
||||
}
|
||||
#[cfg(all(feature = "json-cfg", not(feature = "yaml-cfg")))]
|
||||
{
|
||||
ConfigFmt::Json
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
-30
@@ -1,4 +1,3 @@
|
||||
use std::default::Default;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, Read, Write};
|
||||
@@ -14,6 +13,7 @@ mod buffer;
|
||||
mod cmd;
|
||||
mod color;
|
||||
mod config;
|
||||
mod configfmt;
|
||||
mod desktop;
|
||||
mod doublemempool;
|
||||
mod draw;
|
||||
@@ -22,13 +22,15 @@ mod widgets;
|
||||
|
||||
use app::{App, OutputMode};
|
||||
use cmd::Cmd;
|
||||
use config::Config;
|
||||
use configfmt::ConfigFmt;
|
||||
|
||||
enum Mode {
|
||||
Start,
|
||||
Daemonize,
|
||||
StartOrKill,
|
||||
ToggleVisible,
|
||||
PrintConfig(bool),
|
||||
PrintConfig(ConfigFmt),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@@ -44,40 +46,61 @@ fn main() {
|
||||
},
|
||||
};
|
||||
|
||||
let (is_yaml, config): (bool, config::Config) = match File::open(config_home.clone() + "/config.yaml") {
|
||||
Ok(f) => {
|
||||
let reader = BufReader::new(f);
|
||||
(true, serde_yaml::from_reader(reader).unwrap())
|
||||
}
|
||||
Err(_) => match File::open(config_home + "/config.json") {
|
||||
Ok(f) => {
|
||||
let reader = BufReader::new(f);
|
||||
(false, serde_json::from_reader(reader).unwrap())
|
||||
// From all existing files take the first readable one and write it's extension to `ext`
|
||||
let mut ext = [0x0; 8];
|
||||
let file = configfmt::CONFIG_NAMES
|
||||
.iter()
|
||||
.map(|name| std::path::Path::new(&config_home).join(name))
|
||||
.filter_map(|path| {
|
||||
match File::open(&path) {
|
||||
Ok(file) => {
|
||||
let e = path.extension().and_then(|e| e.to_str())?;
|
||||
let len = e.len();
|
||||
let from = len.saturating_sub(8); // the longest possible extension
|
||||
ext[0..len - from].copy_from_slice(&e.as_bytes()[from..]);
|
||||
Some(file)
|
||||
}
|
||||
Err(_) => None,
|
||||
}
|
||||
Err(_) => (true, Default::default()),
|
||||
}
|
||||
};
|
||||
})
|
||||
.next();
|
||||
|
||||
let fmt = std::str::from_utf8(&ext)
|
||||
.ok()
|
||||
.and_then(ConfigFmt::new)
|
||||
.unwrap_or_default();
|
||||
|
||||
let config: Config = file
|
||||
.map(|f| fmt.from_reader(BufReader::new(f)))
|
||||
.unwrap_or_default();
|
||||
|
||||
let scale = config.scale;
|
||||
|
||||
let mut args = env::args();
|
||||
let _ = args.next();
|
||||
let mode = match args.next() {
|
||||
Some(arg) => {
|
||||
match arg.as_str() {
|
||||
"start" => Mode::Daemonize,
|
||||
"start-or-kill" => Mode::StartOrKill,
|
||||
"toggle-visible" => Mode::ToggleVisible,
|
||||
"print-config" => Mode::PrintConfig(!is_yaml),
|
||||
"print-config-json" => Mode::PrintConfig(true),
|
||||
"print-config-yaml" => Mode::PrintConfig(false),
|
||||
s => {
|
||||
Some(arg) => match arg.as_str() {
|
||||
"start" => Mode::Daemonize,
|
||||
"start-or-kill" => Mode::StartOrKill,
|
||||
"toggle-visible" => Mode::ToggleVisible,
|
||||
"print-config" => Mode::PrintConfig(fmt),
|
||||
s => {
|
||||
let p = "print-config-";
|
||||
let l = p.len();
|
||||
let fmt = if s.starts_with(p) {
|
||||
ConfigFmt::new(&s[l..])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(fmt) = fmt {
|
||||
Mode::PrintConfig(fmt)
|
||||
} else {
|
||||
eprintln!("unsupported sub-command {}", s);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => Mode::Start
|
||||
None => Mode::Start,
|
||||
};
|
||||
if let Some(_) = args.next() {
|
||||
// total = args.count + 2 (the two we skipped + the rest)
|
||||
@@ -115,12 +138,8 @@ fn main() {
|
||||
};
|
||||
daemon = true;
|
||||
}
|
||||
Mode::PrintConfig(json) => {
|
||||
if json {
|
||||
println!("{}", serde_json::to_string_pretty(&config).unwrap());
|
||||
} else {
|
||||
println!("{}", serde_yaml::to_string(&config).unwrap());
|
||||
}
|
||||
Mode::PrintConfig(fmt) => {
|
||||
println!("{}", fmt.to_string(&config));
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,5 +6,5 @@ pub mod clock;
|
||||
pub mod date;
|
||||
pub mod launcher;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[cfg(any(feature="alsa-widget", feature="pulseaudio-widget"))]
|
||||
pub mod audio;
|
||||
|
||||
Reference in New Issue
Block a user