better error handling using Result instead of panic
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -192,7 +192,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swayout"
|
name = "swayout"
|
||||||
version = "1.2.1"
|
version = "1.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kdl",
|
"kdl",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "swayout"
|
name = "swayout"
|
||||||
version = "1.2.1"
|
version = "1.2.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "A tool to configure sway outputs"
|
description = "A tool to configure sway outputs"
|
||||||
authors = ["Stephen Byrne"]
|
authors = ["Stephen Byrne"]
|
||||||
|
|||||||
62
src/lib.rs
62
src/lib.rs
@@ -135,7 +135,7 @@ pub fn print_layout_names() {
|
|||||||
/// or the name of an output.
|
/// or the name of an output.
|
||||||
/// Return true of any outputs were enabled.
|
/// Return true of any outputs were enabled.
|
||||||
/// Return false if there were no outputs to enable and thus nothing was done.
|
/// Return false if there were no outputs to enable and thus nothing was done.
|
||||||
pub fn apply_layout(layout_name: &String) -> bool {
|
pub fn apply_layout(layout_name: &String) -> Result<(), String> {
|
||||||
let config = get_config();
|
let config = get_config();
|
||||||
let outputs = get_outputs();
|
let outputs = get_outputs();
|
||||||
let monitor_states = get_monitor_states(&config, &outputs);
|
let monitor_states = get_monitor_states(&config, &outputs);
|
||||||
@@ -151,15 +151,21 @@ pub fn apply_layout(layout_name: &String) -> bool {
|
|||||||
.find(|layout| &layout.name == layout_name)
|
.find(|layout| &layout.name == layout_name)
|
||||||
{
|
{
|
||||||
// The layout is defined in the config.
|
// The layout is defined in the config.
|
||||||
layout
|
for (monitor_name, output_config) in &layout.outputs {
|
||||||
.outputs
|
// there is probably a syntactic sugar for this?
|
||||||
.iter()
|
let monitor_state = if let Some(monitor_state) =
|
||||||
.for_each(|(monitor_name, output_config)| {
|
get_monitor_state_by_name(&monitor_states, &monitor_name)
|
||||||
let monitor_state = get_monitor_state_by_name(&monitor_states, &monitor_name)
|
{
|
||||||
.unwrap_or_else(||panic!("Cannot find monitor '{}' for layout '{}'", monitor_name, layout_name));
|
monitor_state
|
||||||
|
} else {
|
||||||
|
return Err(format!(
|
||||||
|
"Cannot find monitor '{}' for layout '{}'",
|
||||||
|
monitor_name, layout_name
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
if monitor_state.is_lid_closed {
|
if monitor_state.is_lid_closed {
|
||||||
panic!("Monitor '{}' is closed", monitor_name);
|
return Err(format!("Monitor '{}' is closed.", monitor_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the output for the monitor to get the output name.
|
// find the output for the monitor to get the output name.
|
||||||
@@ -169,15 +175,18 @@ pub fn apply_layout(layout_name: &String) -> bool {
|
|||||||
if let Some(output) = output_opt {
|
if let Some(output) = output_opt {
|
||||||
output_config_map.insert(&output.name, &output_config);
|
output_config_map.insert(&output.name, &output_config);
|
||||||
} else {
|
} else {
|
||||||
panic!("Missing output for monitor '{monitor_name}'");
|
return Err(format!("Missing output for monitor '{}'.", monitor_name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// The layout is not defined in the rules.
|
// The layout is not defined in the rules.
|
||||||
// See if it is a monitor name...
|
// See if it is a monitor name...
|
||||||
if let Some(monitor_state) = get_monitor_state_by_name(&monitor_states, &layout_name) {
|
if let Some(monitor_state) = get_monitor_state_by_name(&monitor_states, &layout_name) {
|
||||||
if monitor_state.is_lid_closed {
|
if monitor_state.is_lid_closed {
|
||||||
panic!("Monitor '{}' is closed", &monitor_state.monitor.name);
|
return Err(format!(
|
||||||
|
"Monitor '{}' is closed.",
|
||||||
|
&monitor_state.monitor.name
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is a monitor name. Find the matching output...
|
// It is a monitor name. Find the matching output...
|
||||||
@@ -187,29 +196,34 @@ pub fn apply_layout(layout_name: &String) -> bool {
|
|||||||
{
|
{
|
||||||
output_config_map.insert(&output.name, &output.output_config);
|
output_config_map.insert(&output.name, &output.output_config);
|
||||||
} else {
|
} else {
|
||||||
panic!("Could not find output for monitor '{layout_name}'")
|
return Err(format!(
|
||||||
|
"Could not find output for monitor '{}'.",
|
||||||
|
layout_name
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// See if it is an output name...
|
// See if it is an output name...
|
||||||
if let Some(output) = outputs.iter().find(|output| &output.name == layout_name) {
|
if let Some(output) = outputs.iter().find(|output| &output.name == layout_name) {
|
||||||
output_config_map.insert(&output.name, &output.output_config);
|
output_config_map.insert(&output.name, &output.output_config);
|
||||||
} else {
|
} else {
|
||||||
panic!("Could not find layout, monitor, or output '{layout_name}'")
|
return Err(format!(
|
||||||
|
"Could not find layout, monitor, or output '{}.'",
|
||||||
|
layout_name
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ! output_config_map.is_empty() {
|
if output_config_map.is_empty() {
|
||||||
apply_outputs(&outputs, &output_config_map);
|
return Err("No outputs would be enabled. Do nothing.".to_string());
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply_outputs(&outputs, &output_config_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the first automatic layout for which all outputs are available.
|
/// Apply the first automatic layout for which all outputs are available.
|
||||||
/// Return the name of the layout applied or None if no automatic layout was available.
|
/// Return the name of the layout applied or None if no automatic layout was available.
|
||||||
pub fn apply_automatic() -> Option<String> {
|
pub fn apply_automatic() -> Result<String,String> {
|
||||||
let outputs = get_outputs();
|
let outputs = get_outputs();
|
||||||
|
|
||||||
let config = get_config();
|
let config = get_config();
|
||||||
@@ -219,12 +233,10 @@ pub fn apply_automatic() -> Option<String> {
|
|||||||
.iter()
|
.iter()
|
||||||
.find(|layout| layout.automatic)
|
.find(|layout| layout.automatic)
|
||||||
{
|
{
|
||||||
if apply_layout(&layout.name) {
|
|
||||||
Some(String::from(&layout.name))
|
apply_layout(&layout.name)?;
|
||||||
|
Ok(String::from(&layout.name))
|
||||||
} else {
|
} else {
|
||||||
None
|
Err("No automatic layouts available.".to_string())
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/main.rs
12
src/main.rs
@@ -8,14 +8,18 @@ fn main() {
|
|||||||
} else if args.len() == 2 {
|
} else if args.len() == 2 {
|
||||||
let arg = &args[1];
|
let arg = &args[1];
|
||||||
if arg == "--automatic" {
|
if arg == "--automatic" {
|
||||||
if let Some(layout_name) = swayout::apply_automatic() {
|
match swayout::apply_automatic() {
|
||||||
|
Ok(layout_name) => {
|
||||||
println!("{}", layout_name);
|
println!("{}", layout_name);
|
||||||
} else {
|
}
|
||||||
eprintln!("no automatic layout available");
|
Err(e) => {
|
||||||
|
eprintln!("{}", e);
|
||||||
process::exit(2)
|
process::exit(2)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ! swayout::apply_layout(&args[1]) {
|
if let Err(e) = swayout::apply_layout(&args[1]) {
|
||||||
|
eprintln!("{}", e);
|
||||||
process::exit(3)
|
process::exit(3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,10 @@ fn get_mode(output: &Value) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the specified outputs. Enable all outputs in [outputs], disable others.
|
/// Apply the specified outputs. Enable all outputs in [outputs], disable others.
|
||||||
pub fn apply_outputs(all_outputs: &Vec<Output>, outputs: &HashMap<&String, &OutputConfig>) {
|
pub fn apply_outputs(
|
||||||
|
all_outputs: &Vec<Output>,
|
||||||
|
outputs: &HashMap<&String, &OutputConfig>,
|
||||||
|
) -> Result<(), String> {
|
||||||
// set enabled outputs first, then set disabled outputs.
|
// set enabled outputs first, then set disabled outputs.
|
||||||
// That way if some work before an error, you have at least one output enabled.
|
// That way if some work before an error, you have at least one output enabled.
|
||||||
|
|
||||||
@@ -85,7 +88,7 @@ pub fn apply_outputs(all_outputs: &Vec<Output>, outputs: &HashMap<&String, &Outp
|
|||||||
});
|
});
|
||||||
|
|
||||||
if enabled.is_empty() {
|
if enabled.is_empty() {
|
||||||
panic!("No enabled outputs!");
|
return Err("No enabled outputs!".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cmd = Command::new("swaymsg");
|
let mut cmd = Command::new("swaymsg");
|
||||||
@@ -117,4 +120,6 @@ pub fn apply_outputs(all_outputs: &Vec<Output>, outputs: &HashMap<&String, &Outp
|
|||||||
.for_each(|arg| print!("{} ", arg.to_str().unwrap()));
|
.for_each(|arg| print!("{} ", arg.to_str().unwrap()));
|
||||||
|
|
||||||
cmd.output().expect("swaymsg output failed");
|
cmd.output().expect("swaymsg output failed");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user