Move config parsing to util crate

This commit is contained in:
2022-05-04 15:37:28 -07:00
parent 7ef720467f
commit fcb997bfb3
7 changed files with 110 additions and 108 deletions

View File

@ -9,6 +9,7 @@ edition = "2021"
anyhow = "1"
clap = "3"
env_logger = "0.9"
humantime = "2"
lazy_static = "1"
libc = "0.2"
toml = "0.5"

View File

@ -1,7 +1,8 @@
use std::{ffi::CStr, fs::File, io::{self, Read}, path::PathBuf};
use toml::Value;
use std::{ffi::CStr, io};
use xcb::x;
pub mod settings;
pub const BSCREENSAVER_WM_CLASS: &[u8] = b"bscreensaver\0Bscreensaver\0";
pub fn init_logging(env_name: &str) {
@ -11,23 +12,6 @@ pub fn init_logging(env_name: &str) {
.init();
}
fn parse_config_toml(config_path: &PathBuf) -> anyhow::Result<Value> {
let mut f = File::open(config_path)?;
let mut config = String::new();
f.read_to_string(&mut config)?;
drop(f);
let config_toml = config.parse::<Value>()?;
Ok(config_toml)
}
pub fn load_configuration() -> anyhow::Result<Vec<Value>> {
xdg::BaseDirectories::new()?
.find_config_files("bscreensaver/bscreensaver.toml")
.map(|config_path| parse_config_toml(&config_path))
.collect()
}
pub fn create_atom(conn: &xcb::Connection, name: &[u8]) -> xcb::Result<x::Atom> {
let cookie = conn.send_request(&x::InternAtom {
only_if_exists: false,

94
util/src/settings.rs Normal file
View File

@ -0,0 +1,94 @@
use anyhow::anyhow;
use std::{fs::File, io::Read, path::PathBuf, time::Duration};
use toml::Value;
#[derive(Debug, Clone, Copy)]
pub enum DialogBackend {
Gtk3,
}
impl DialogBackend {
pub fn binary_name(&self) -> &str {
match self {
Self::Gtk3 => "bscreensaver-dialog-gtk3",
}
}
}
impl TryFrom<&str> for DialogBackend {
type Error = anyhow::Error;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"gtk3" => Ok(Self::Gtk3),
other => Err(anyhow!("'{}' is not a valid dialog backend (valid: 'gtk3')", other)),
}
}
}
#[derive(Debug, Clone)]
pub struct Configuration {
pub lock_timeout: Duration,
pub blank_before_locking: Duration,
pub dialog_backend: DialogBackend,
pub new_login_command: Option<String>,
}
impl Configuration {
pub fn load() -> anyhow::Result<Configuration> {
use humantime::parse_duration;
let config_tomls = xdg::BaseDirectories::new()?
.find_config_files("bscreensaver/bscreensaver.toml")
.map(|config_path| parse_config_toml(&config_path))
.collect::<Result<Vec<Value>, _>>()?;
let mut config = Configuration::default();
for config_toml in config_tomls {
config.lock_timeout = match config_toml.get("lock-timeout") {
None => config.lock_timeout,
Some(val) => parse_duration(val.as_str().ok_or(anyhow!("'lock-timeout' must be a duration string like '10m' or '90s'"))?)?,
};
config.blank_before_locking = match config_toml.get("blank-before-locking") {
None => config.blank_before_locking,
Some(val) => parse_duration(val.as_str().ok_or(anyhow!("'blank-before-locking' must be a duration string like '10m' or '90s'"))?)?,
};
config.dialog_backend = match config_toml.get("dialog-backend") {
None => config.dialog_backend,
Some(val) => DialogBackend::try_from(val.as_str().ok_or(anyhow!("'dialog-backend' must be a string"))?)?,
};
config.new_login_command = match config_toml.get("new-login-command") {
None => config.new_login_command,
Some(val) => val.as_str().map(|s| s.to_string()),
};
}
if config.blank_before_locking >= config.lock_timeout {
Err(anyhow!("'blank-before-locking' cannot be greater than 'lock-timeout'"))
} else {
Ok(config)
}
}
}
fn parse_config_toml(config_path: &PathBuf) -> anyhow::Result<Value> {
let mut f = File::open(config_path)?;
let mut config = String::new();
f.read_to_string(&mut config)?;
drop(f);
let config_toml = config.parse::<Value>()?;
Ok(config_toml)
}
impl Default for Configuration {
fn default() -> Self {
Self {
lock_timeout: Duration::from_secs(60 * 10),
blank_before_locking: Duration::ZERO,
dialog_backend: DialogBackend::Gtk3,
new_login_command: None,
}
}
}