From bec2bdc8f9cb16a4513346102f485a57dae1d84b Mon Sep 17 00:00:00 2001 From: stephen Date: Mon, 30 Dec 2024 03:30:08 +0000 Subject: [PATCH] separate config module --- src/config.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 91 ++------------------------------------------------- 2 files changed, 94 insertions(+), 88 deletions(-) create mode 100644 src/config.rs diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..0ce806e --- /dev/null +++ b/src/config.rs @@ -0,0 +1,91 @@ +use std::collections::HashMap; +use std::fs; +use kdl::KdlDocument; + +/// Configuration for swayout. +pub struct Config { + /// Monitor name is independent of output name. It can be anything. + pub monitors: HashMap, + /// Definition of layouts: a map of the layout name to the outputs. + /// The outputs is a map of the monitor name (in `monitors`) to the configuration + /// of that monitor for this layout. + /// Available outputs that do not match a monitor in the map are disabled. + pub layouts: HashMap>, +} + +/// Defines a monitor by make, model, and serial. +pub struct Monitor { + pub make: String, + pub model: String, + pub serial: String, +} + +/// Configuration for an enabled output. +pub struct OutputConfig { + /// mode. See man 5 sway-output + pub mode: String, + /// scale. See man 5 sway-output + pub scale: String, + /// x value for position. See man 5 sway-output + pub x: u16, + /// y value for position. See man 5 sway-output + pub y: u16, + /// transform. See man 5 sway-output + pub transform: String, +} + +/// Get a `Config` from ~/.config/swayout/config.kdl. +/// (It really uses XDG config dirs.) +pub fn get_config() -> Config { + let xdg_dirs = xdg::BaseDirectories::with_prefix("swayout").unwrap(); + if let Some(path) = xdg_dirs.find_config_file("config.kdl") { + let kdl = fs::read_to_string(path).expect("error reading file"); + parse_config(kdl) + } else { + // no config files, use an empty rules + Config { + monitors: HashMap::new(), + layouts: HashMap::new(), + } + } +} +fn parse_config(kdl:String) -> Config { + let doc:KdlDocument = kdl.parse().expect("failed to parse config KDL"); + + let monitors:HashMap = doc.nodes().iter() + .filter(|node| node.name().value() == "monitor") + .map(|monitor_node| { + let name = String::from(monitor_node[0].as_string().unwrap()); + let monitor = Monitor { + make : String::from(monitor_node["make"].as_string().unwrap()), + model : String::from(monitor_node["model"].as_string().unwrap()), + serial : String::from(monitor_node["serial"].as_string().unwrap()), + }; + (name, monitor) + }) + .collect(); + + let layouts:HashMap> = doc.nodes().iter() + .filter(|node| node.name().value() == "layout") + .map(|layout_node| { + let layout_name = String::from(layout_node[0].as_string().unwrap()); + let monitor_name_to_output_config:HashMap = layout_node + .children().unwrap().nodes().iter() + .map(|output_node| { + let output = String::from(output_node[0].as_string().unwrap()); + let output_config = OutputConfig { + mode : String::from(output_node["mode"].as_string().unwrap()), + scale : String::from(output_node["scale"].as_string().unwrap()), + transform : String::from(output_node["transform"].as_string().unwrap()), + x : output_node["x"].as_i64().unwrap() as u16, + y : output_node["y"].as_i64().unwrap() as u16, + }; + (output, output_config) + }) + .collect(); + (layout_name,monitor_name_to_output_config) + }) + .collect(); + + Config { monitors, layouts } +} diff --git a/src/lib.rs b/src/lib.rs index 8af32f7..c2c825d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,40 +1,11 @@ -use kdl::KdlDocument; use serde_json::{from_str, Value}; use std::collections::HashMap; use std::process::Command; -use std::{fs, str}; +use std::str; -/// Configuration for swayout. -struct Config { - /// Monitor name is independent of output name. It can be anything. - monitors: HashMap, - /// Definition of layouts: a map of the layout name to the outputs. - /// The outputs is a map of the monitor name (in `monitors`) to the configuration - /// of that monitor for this layout. - /// Available outputs that do not match a monitor in the map are disabled. - layouts: HashMap>, -} +pub mod config; -/// Defines a monitor by make, model, and serial. -struct Monitor { - make: String, - model: String, - serial: String, -} - -/// Configuration for an enabled output. -struct OutputConfig { - /// mode. See man 5 sway-output - mode: String, - /// scale. See man 5 sway-output - scale: String, - /// x value for position. See man 5 sway-output - x: u16, - /// y value for position. See man 5 sway-output - y: u16, - /// transform. See man 5 sway-output - transform: String, -} +use crate::config::{get_config,OutputConfig}; /// An output, as returned by `swaymsg -t get_outputs`. struct Output { @@ -98,62 +69,6 @@ fn get_mode(output: &Value) -> String { } } -/// Get a `Config` from ~/.config/swayout/config.kdl. -/// (It really uses XDG config dirs.) -fn get_config() -> Config { - let xdg_dirs = xdg::BaseDirectories::with_prefix("swayout").unwrap(); - if let Some(path) = xdg_dirs.find_config_file("config.kdl") { - let kdl = fs::read_to_string(path).expect("error reading file"); - parse_config(kdl) - } else { - // no config files, use an empty rules - Config { - monitors: HashMap::new(), - layouts: HashMap::new(), - } - } -} -fn parse_config(kdl:String) -> Config { - let doc:KdlDocument = kdl.parse().expect("failed to parse config KDL"); - - let monitors:HashMap = doc.nodes().iter() - .filter(|node| node.name().value() == "monitor") - .map(|monitor_node| { - let name = String::from(monitor_node[0].as_string().unwrap()); - let monitor = Monitor { - make : String::from(monitor_node["make"].as_string().unwrap()), - model : String::from(monitor_node["model"].as_string().unwrap()), - serial : String::from(monitor_node["serial"].as_string().unwrap()), - }; - (name, monitor) - }) - .collect(); - - let layouts:HashMap> = doc.nodes().iter() - .filter(|node| node.name().value() == "layout") - .map(|layout_node| { - let layout_name = String::from(layout_node[0].as_string().unwrap()); - let monitor_name_to_output_config:HashMap = layout_node - .children().unwrap().nodes().iter() - .map(|output_node| { - let output = String::from(output_node[0].as_string().unwrap()); - let output_config = OutputConfig { - mode : String::from(output_node["mode"].as_string().unwrap()), - scale : String::from(output_node["scale"].as_string().unwrap()), - transform : String::from(output_node["transform"].as_string().unwrap()), - x : output_node["x"].as_i64().unwrap() as u16, - y : output_node["y"].as_i64().unwrap() as u16, - }; - (output, output_config) - }) - .collect(); - (layout_name,monitor_name_to_output_config) - }) - .collect(); - - Config { monitors, layouts } -} - /// Determine the available layout names. /// Return one layout for each layout defined in the configuration file /// for which all outputs are available,