Skip to content

Commit

Permalink
Added error handling and fixed tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
apognu committed Sep 29, 2024
1 parent 9f916a9 commit 777e054
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 41 deletions.
15 changes: 6 additions & 9 deletions src/config/file.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::{error::Error, path::PathBuf};
use std::path::PathBuf;

use serde::Deserialize;

use crate::Greeter;

#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct FileConfig {
#[serde(default)]
pub defaults: Defaults,
Expand All @@ -17,6 +16,7 @@ pub struct FileConfig {
}

#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Defaults {
pub debug: Option<String>,
pub command: Option<String>,
Expand All @@ -30,6 +30,7 @@ pub struct Defaults {
}

#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Sessions {
pub wayland_paths: Option<Vec<PathBuf>>,
pub wayland_wrapper: Option<String>,
Expand All @@ -40,6 +41,7 @@ pub struct Sessions {
}

#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Remember {
#[serde(default)]
pub last_user: bool,
Expand All @@ -50,6 +52,7 @@ pub struct Remember {
}

#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Ui {
pub greeting: Option<String>,
#[serde(default)]
Expand All @@ -70,9 +73,3 @@ pub struct Ui {
pub sessions_f_key: Option<u8>,
pub power_f_key: Option<u8>,
}

impl Greeter {
pub fn parse_config_file(&mut self, file: &str) -> Result<FileConfig, Box<dyn Error>> {
Ok(toml::from_str::<FileConfig>(file)?)
}
}
22 changes: 17 additions & 5 deletions src/config/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl Greeter {
self.session_wrapper = self.option("session-wrapper").or_else(|| self.config.sessions.wayland_wrapper.clone());
}

if !self.config().opt_present("no-xsession-wrapper") && self.config.sessions.x11_wrapper_disabled {
if !self.config().opt_present("no-xsession-wrapper") && !self.config.sessions.x11_wrapper_disabled {
self.xsession_wrapper = self
.option("xsession-wrapper")
.or_else(|| self.config.sessions.x11_wrapper.clone())
Expand Down Expand Up @@ -277,19 +277,30 @@ mod tests {
(&["--cmd", "cmd", "--env", "A"], false, None),
];

for (opts, valid, check) in table {
for (args, valid, check) in table {
let mut greeter = Greeter::default();
let opts = greeter.parse_opts(*args);

let result = match opts {
Ok(opts) => {
greeter.opts = opts;
greeter.parse_config().await.ok()
}

Err(_) => None,
};

match valid {
true => {
assert!(matches!(greeter.parse_options(*opts).await, Ok(())), "{:?} cannot be parsed", opts);
assert!(result.is_some(), "{:?} cannot be parsed", args);
assert!(matches!(greeter.parse_config().await, Ok(())), "{:?} cannot be parsed", greeter.opts);

if let Some(check) = check {
check(&greeter);
}
}

false => assert!(matches!(greeter.parse_options(*opts).await, Err(_))),
false => assert!(result.is_none(), "{:?} should not have been parsed", args),
}
}
}
Expand Down Expand Up @@ -321,11 +332,12 @@ mod tests {

for (opts, file, check) in table {
let mut greeter = Greeter::default();
greeter.opts = greeter.parse_opts(*opts).unwrap();
greeter.config = FileConfig::default();

file(&mut greeter.config);

assert!(matches!(greeter.parse_options(*opts).await, Ok(())), "{:?} cannot be parsed", opts);
assert!(matches!(greeter.parse_config().await, Ok(())), "{:?} cannot be parsed", opts);

check(&greeter);
}
Expand Down
61 changes: 34 additions & 27 deletions src/greeter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,32 +212,42 @@ impl Greeter {

let args = env::args().collect::<Vec<String>>();

if let Err(err) = greeter.parse_options(&args).await {
eprintln!("{err}");
print_usage(Greeter::options());
match greeter.parse_opts(&args) {
Ok(opts) => greeter.opts = opts,
Err(err) => {
eprintln!("{err}");
print_usage(Greeter::options());

process::exit(1);
process::exit(1);
}
}

greeter.config = if let Some(config_file) = greeter.config().opt_str("config") {
if let Ok(config) = fs::read_to_string(config_file) {
match greeter.parse_config_file(&config) {
match fs::read_to_string(config_file) {
Ok(config) => match toml::from_str::<FileConfig>(&config) {
Ok(config) => config,
Err(err) => {
eprintln!("{err}");
print_usage(Greeter::options());

eprintln!("ERROR: could not parse configuration file: {err}");
process::exit(1);
}
},

Err(err) => {
eprintln!("ERROR: could not open configuration file: {err}");
process::exit(1);
}
} else {
// TODO: add error here.
FileConfig::default()
}
} else {
FileConfig::default()
};

if let Err(err) = greeter.parse_config().await {
eprintln!("{err}");
print_usage(Greeter::options());

process::exit(1);
}

greeter.connect().await;
}

Expand Down Expand Up @@ -482,27 +492,30 @@ impl Greeter {
opts
}

// Parses command line arguments to configured the software accordingly.
pub async fn parse_options<S>(&mut self, args: &[S]) -> Result<(), Box<dyn Error>>
pub fn parse_opts<S>(&mut self, args: &[S]) -> Result<Option<Matches>, Box<dyn Error>>
where
S: AsRef<OsStr>,
{
let opts = Greeter::options();

self.opts = match opts.parse(args) {
Ok(matches) => Some(matches),
Err(err) => return Err(err.into()),
};
Ok(Some(Greeter::options().parse(args)?))
}

// Parses command line arguments to configured the software accordingly.
pub async fn parse_config(&mut self) -> Result<(), Box<dyn Error>> {
if self.config().opt_present("help") {
print_usage(opts);
print_usage(Greeter::options());
process::exit(0);
}
if self.config().opt_present("version") {
print_version();
process::exit(0);
}

if self.config().opt_present("theme") {
if let Some(spec) = self.config().opt_str("theme") {
self.theme = Theme::parse(spec.as_str());
}
}

self.parse_debug();
self.parse_greeting()?;
self.parse_asterisks()?;
Expand All @@ -514,12 +527,6 @@ impl Greeter {
self.parse_power();
self.parse_keybinds()?;

if self.config().opt_present("theme") {
if let Some(spec) = self.config().opt_str("theme") {
self.theme = Theme::parse(spec.as_str());
}
}

Ok(())
}

Expand Down

0 comments on commit 777e054

Please sign in to comment.