Move config parsing to util crate
This commit is contained in:
parent
7ef720467f
commit
fcb997bfb3
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -260,7 +260,6 @@ dependencies = [
|
||||
"bscreensaver-command",
|
||||
"bscreensaver-util",
|
||||
"clap",
|
||||
"humantime",
|
||||
"log",
|
||||
"nix",
|
||||
"xcb",
|
||||
@ -333,6 +332,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"humantime",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"toml",
|
||||
@ -1088,9 +1088,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
@ -6,7 +6,7 @@ use gtk::{prelude::*, Button, Entry, Label, Plug, Window};
|
||||
use log::{debug, error, warn};
|
||||
use std::{io::{self, Write}, process::{exit, Command}, rc::Rc, thread, time::Duration};
|
||||
|
||||
use bscreensaver_util::{init_logging, load_configuration};
|
||||
use bscreensaver_util::{init_logging, settings::Configuration};
|
||||
|
||||
const DIALOG_UPDATE_INTERVAL: Duration = Duration::from_millis(100);
|
||||
const DIALOG_TIMEOUT: Duration = Duration::from_secs(60);
|
||||
@ -14,21 +14,11 @@ const DIALOG_TIMEOUT: Duration = Duration::from_secs(60);
|
||||
fn main() -> anyhow::Result<()> {
|
||||
init_logging("BSCREENSAVER_DIALOG_GTK3_LOG");
|
||||
|
||||
let config_tomls = load_configuration()?;
|
||||
let mut config_tomls_iter = config_tomls.into_iter().rev();
|
||||
let mut new_login_command: Option<Vec<String>> = loop {
|
||||
if let Some(config_toml) = config_tomls_iter.next() {
|
||||
if let Some(nlc) = config_toml.get("new-login-command")
|
||||
.and_then(|nlc| nlc.as_str().map(|s| s.to_string()))
|
||||
let mut config = Configuration::load()?;
|
||||
let new_login_command = config.new_login_command
|
||||
.take()
|
||||
.map(|nlc| shell_words::split(&nlc))
|
||||
.transpose()?
|
||||
{
|
||||
break Some(nlc);
|
||||
}
|
||||
} else {
|
||||
break None;
|
||||
}
|
||||
};
|
||||
.transpose()?;
|
||||
|
||||
let standalone = std::env::var("BSCREENSAVER_DIALOG_STANDALONE").is_ok();
|
||||
|
||||
@ -224,7 +214,7 @@ fn main() -> anyhow::Result<()> {
|
||||
.build();
|
||||
vbox.pack_start(&hbox, true, true, 2);
|
||||
|
||||
if let Some(new_login_command) = new_login_command.take() {
|
||||
if let Some(new_login_command) = new_login_command {
|
||||
let new_login_button = Button::builder()
|
||||
.label("New Login")
|
||||
.build();
|
||||
|
@ -17,7 +17,6 @@ anyhow = "1"
|
||||
clap = "3"
|
||||
bscreensaver-command = { path = "../command" }
|
||||
bscreensaver-util = { path = "../util" }
|
||||
humantime = "2"
|
||||
log = "0.4"
|
||||
nix = "0.23"
|
||||
# git source needed until extension event error resolution fix is released
|
||||
|
@ -1,7 +1,6 @@
|
||||
#![feature(linux_pidfd)]
|
||||
#![feature(option_result_contains)]
|
||||
|
||||
use anyhow::anyhow;
|
||||
use clap::{Arg, Command as ClapCommand};
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use nix::{
|
||||
@ -29,50 +28,11 @@ use xcb::{randr, x, xinput, Xid};
|
||||
use xcb_xembed::embedder::Embedder;
|
||||
|
||||
use bscreensaver_command::{BCommand, create_command_window};
|
||||
use bscreensaver_util::*;
|
||||
use bscreensaver_util::{*, settings::Configuration};
|
||||
|
||||
const BLANKED_ARG: &str = "blanked";
|
||||
const LOCKED_ARG: &str = "locked";
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Configuration {
|
||||
lock_timeout: Duration,
|
||||
blank_before_locking: Duration,
|
||||
dialog_backend: DialogBackend,
|
||||
}
|
||||
|
||||
impl Default for Configuration {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
lock_timeout: Duration::from_secs(60 * 10),
|
||||
blank_before_locking: Duration::ZERO,
|
||||
dialog_backend: DialogBackend::Gtk3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Monitor {
|
||||
pub root: x::Window,
|
||||
@ -132,7 +92,7 @@ macro_rules! maybe_add_fd {
|
||||
fn main() -> anyhow::Result<()> {
|
||||
init_logging("BSCREENSAVER_LOG");
|
||||
|
||||
let config = parse_config()?;
|
||||
let config = Configuration::load()?;
|
||||
|
||||
let args = ClapCommand::new("Blanks and locks the screen after a period of time")
|
||||
.author(env!("CARGO_PKG_AUTHORS"))
|
||||
@ -275,32 +235,6 @@ fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_config() -> anyhow::Result<Configuration> {
|
||||
use humantime::parse_duration;
|
||||
|
||||
let mut config = Configuration::default();
|
||||
for config_toml in load_configuration()? {
|
||||
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"))?)?,
|
||||
};
|
||||
|
||||
if config.blank_before_locking >= config.lock_timeout {
|
||||
Err(anyhow!("'blank-before-locking' cannot be greater than 'lock-timeout'"))?
|
||||
}
|
||||
}
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
fn init_signals() -> anyhow::Result<SignalFd> {
|
||||
let sigs = {
|
||||
let mut s = SigSet::empty();
|
||||
|
@ -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"
|
||||
|
@ -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
94
util/src/settings.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user