From e992ac7ad05e0f10b8c229ccf51dfdc871dd97e1 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sat, 6 Mar 2021 14:25:36 -0800 Subject: [PATCH] lua: add `wezterm.battery_info()` function Queries the system battery information and returns an array of battery information. Each element is a lua table with the following entries: * state_of_charge: expressed as percents * vendor: the battery manufacturer * model: the battery model * serial: the battery serial number * time_to_full: how long until the battery is full * time_to_empty: how long until the battery is empty * state: "Charging", "Discharging", "Empty", "Full", "Unknown" I haven't run this on a system with a battery yet, so I'm holding off from showing an example until I've got a work one. refs: https://github.com/wez/wezterm/issues/500 --- Cargo.lock | 49 +++++++++++++++++++++++++++++++++++++++++++++++ config/Cargo.toml | 1 + config/src/lua.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index f048cd75c..486fe1ea4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -346,6 +346,23 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" name = "base91" version = "0.1.0" +[[package]] +name = "battery" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b624268937c0e0a3edb7c27843f9e547c320d730c610d3b8e6e8e95b2026e4" +dependencies = [ + "cfg-if 1.0.0", + "core-foundation 0.7.0", + "lazycell", + "libc", + "mach", + "nix 0.19.1", + "num-traits 0.2.14", + "uom", + "winapi 0.3.9", +] + [[package]] name = "bintree" version = "0.1.0" @@ -673,6 +690,7 @@ name = "config" version = "0.1.0" dependencies = [ "anyhow", + "battery", "bitflags", "bstr 0.2.15", "chrono", @@ -1937,6 +1955,15 @@ dependencies = [ "cc", ] +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -2211,6 +2238,18 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", +] + [[package]] name = "nix" version = "0.20.0" @@ -4007,6 +4046,16 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "uom" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e76503e636584f1e10b9b3b9498538279561adcef5412927ba00c2b32c4ce5ed" +dependencies = [ + "num-traits 0.2.14", + "typenum", +] + [[package]] name = "url" version = "2.2.1" diff --git a/config/Cargo.toml b/config/Cargo.toml index 317a60b1c..7f4110528 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -15,6 +15,7 @@ pretty_env_logger = "0.4" [dependencies] anyhow = "1.0" +battery = "0.7" bitflags = "1.0" bstr = "0.2" chrono = {version="0.4", features=["unstable-locales"]} diff --git a/config/src/lua.rs b/config/src/lua.rs index 06240b73b..ee73d5cea 100644 --- a/config/src/lua.rs +++ b/config/src/lua.rs @@ -134,6 +134,7 @@ pub fn make_lua_context(config_dir: &Path) -> anyhow::Result { wezterm_mod.set("sleep_ms", lua.create_async_function(sleep_ms)?)?; wezterm_mod.set("format", lua.create_function(format)?)?; wezterm_mod.set("strftime", lua.create_function(strftime)?)?; + wezterm_mod.set("battery_info", lua.create_function(battery_info)?)?; package.set("path", path_array.join(";"))?; @@ -254,6 +255,52 @@ fn format<'lua>(_: &'lua Lua, items: Vec) -> mlua::Result { String::from_utf8(target.target).map_err(|e| mlua::Error::external(e)) } +#[derive(Serialize, Deserialize, Debug)] +struct BatteryInfo { + state_of_charge: f32, + vendor: String, + model: String, + state: String, + serial: String, + time_to_full: Option, + time_to_empty: Option, +} +impl_lua_conversion!(BatteryInfo); + +fn opt_string(s: Option<&str>) -> String { + match s { + Some(s) => s, + None => "unknown", + } + .to_string() +} + +fn battery_info<'lua>(_: &'lua Lua, _: ()) -> mlua::Result> { + use battery::{Manager, State}; + let manager = Manager::new().map_err(|e| mlua::Error::external(e))?; + let mut result = vec![]; + for b in manager.batteries().map_err(|e| mlua::Error::external(e))? { + let bat = b.map_err(|e| mlua::Error::external(e))?; + result.push(BatteryInfo { + state_of_charge: bat.state_of_charge().value, + vendor: opt_string(bat.vendor()), + model: opt_string(bat.model()), + serial: opt_string(bat.serial_number()), + state: match bat.state() { + State::Charging => "charging", + State::Discharging => "Discharging", + State::Empty => "Empty", + State::Full => "Full", + State::Unknown | _ => "Unknown", + } + .to_string(), + time_to_full: bat.time_to_full().map(|q| q.value), + time_to_empty: bat.time_to_empty().map(|q| q.value), + }) + } + Ok(result) +} + async fn sleep_ms<'lua>(_: &'lua Lua, milliseconds: u64) -> mlua::Result<()> { let duration = std::time::Duration::from_millis(milliseconds); smol::Timer::after(duration).await;