diff --git a/src/core/config.rs b/src/core/config.rs new file mode 100644 index 0000000..853f53f --- /dev/null +++ b/src/core/config.rs @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Copyright (c) 2024, Richard Acayan. All rights reserved. + */ + +use std::convert::TryInto; +use std::fs::File; +use yaml_rust2::yaml::Hash; +use yaml_rust2::yaml::LoadError; +use yaml_rust2::yaml::YamlDecoder; +use yaml_rust2::yaml::Yaml; + +#[derive(Debug)] +pub struct Configuration { + longpress: u64, + repeat: u64, + layout: String, + wayland_height: i32, +} + +impl Configuration { + fn load_wayland(&mut self, yaml: &Hash) + { + let height = yaml.get(&Yaml::String(String::from("height"))); + if let Some(height) = height { + let height = match height.as_i64() { + Some(h) => h.try_into().ok(), + None => None, + }; + let height = height.expect("Wayland height should be a 32-bit signed integer"); + self.wayland_height = height; + } + } + + pub fn load() -> Result + { + let mut cfg = Configuration { + longpress: 600, + repeat: 25, + layout: String::from("latn_qwerty_us.xml"), + wayland_height: 185, + }; + + if let Ok(file) = File::open("/etc/unfettered-keyboard.yaml") { + let yaml = YamlDecoder::read(file).decode()?; + let yaml = yaml[0].as_hash().expect("Top-level configuration should be a YAML mapping"); + + let longpress = yaml.get(&Yaml::String(String::from("longpress_ms"))); + if let Some(longpress) = longpress { + let longpress = match longpress.as_i64() { + Some(l) => l.try_into().ok(), + None => None, + }; + let longpress = longpress.expect("Longpress time should be a 64-bit unsigned integer"); + cfg.longpress = longpress; + } + + let repeat = yaml.get(&Yaml::String(String::from("repeat_ms"))); + if let Some(repeat) = repeat { + let repeat = match repeat.as_i64() { + Some(l) => l.try_into().ok(), + None => None, + }; + let repeat = repeat.expect("Repeat interval should be a 64-bit unsigned integer"); + cfg.repeat = repeat; + } + + let layout = yaml.get(&Yaml::String(String::from("layout"))); + if let Some(layout) = layout { + let layout = layout.as_str().expect("Layout should be a YAML string"); + cfg.layout = layout.to_string(); + } + + let wl = yaml.get(&Yaml::String(String::from("wayland"))); + if let Some(wl) = wl { + let wl = wl.as_hash().expect("Wayland configuration should be a YAML mapping"); + cfg.load_wayland(wl); + } + } + + println!("{:?}", cfg); + + Ok(cfg) + } + + #[inline(always)] + pub fn longpress_ms(&self) -> u64 + { + self.longpress + } + + #[inline(always)] + pub fn repeat_ms(&self) -> u64 + { + self.repeat + } + + #[inline(always)] + pub fn layout(&self) -> &str + { + &self.layout + } + + #[inline(always)] + pub fn wayland_height(&self) -> i32 + { + self.wayland_height + } +}