aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2018-05-14 20:15:39 -0400
committerJesse Luehrs <doy@tozt.net>2018-05-14 20:15:39 -0400
commit0f06ac2286397082228f32fc5f9642778cf84d72 (patch)
treedca52e5ac04685a032c6fd8370e3c43aa0318cfc
parentc23295bfea2184a0e4fee405d3f594032828e39b (diff)
downloadfancy-prompt-0f06ac2286397082228f32fc5f9642778cf84d72.tar.gz
fancy-prompt-0f06ac2286397082228f32fc5f9642778cf84d72.zip
factor out os-specific battery detection code
stub out osx for now, will come back with a real implementation later
-rw-r--r--src/power.rs139
-rw-r--r--src/power/mod.rs86
-rw-r--r--src/power/sys/linux.rs45
-rw-r--r--src/power/sys/macos.rs3
-rw-r--r--src/power/sys/mod.rs24
5 files changed, 158 insertions, 139 deletions
diff --git a/src/power.rs b/src/power.rs
deleted file mode 100644
index 6ae762c..0000000
--- a/src/power.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-use std;
-use walkdir;
-
-use std::io::Read;
-
-// XXX maybe extract this out into a separate crate?
-
-#[derive(PartialEq, Eq, Debug, Clone)]
-enum PowerSupplyType {
- AC,
- Battery,
-}
-
-#[derive(Debug)]
-pub struct PowerInfo {
- power_supplies: Vec<PowerSupplyInfo>,
-}
-
-#[derive(Debug, Clone)]
-struct PowerSupplyInfo {
- name: String,
- ty: PowerSupplyType,
- energy_now: Option<u64>,
- energy_full: Option<u64>,
- online: Option<bool>,
-}
-
-impl PowerInfo {
- pub fn new() -> PowerInfo {
- let mut power_supplies = vec![];
- for entry in walkdir::WalkDir::new("/sys/class/power_supply/")
- .min_depth(1)
- .max_depth(1)
- .follow_links(true)
- {
- let entry = entry.unwrap();
-
- let name = entry
- .path()
- .file_name()
- .unwrap()
- .to_string_lossy()
- .into_owned();
- let ty = slurp(entry.path().join("type"))
- .map(|t: String| PowerSupplyType::from_str(&t))
- .expect("couldn't find power supply type");
- let energy_full = slurp(entry.path().join("energy_full"));
- let energy_now = slurp(entry.path().join("energy_now"));
- let online =
- slurp(entry.path().join("online")).map(|n: u8| n != 0);
-
- power_supplies.push(PowerSupplyInfo {
- name,
- ty,
- energy_now,
- energy_full,
- online,
- })
- }
-
- PowerInfo {
- power_supplies,
- }
- }
-
- pub fn battery_usage(&self) -> Option<f64> {
- let mut total_now = 0;
- let mut total_full = 0;
- for battery in self.batteries() {
- if let Some(now) = battery.energy_now {
- total_now += now;
- }
- else {
- return None;
- }
- if let Some(full) = battery.energy_full {
- total_full += full;
- }
- else {
- return None;
- }
- }
-
- if total_full > 0 {
- Some((total_now as f64) / (total_full as f64))
- }
- else {
- None
- }
- }
-
- pub fn charging(&self) -> bool {
- for mains in self.mains() {
- if mains.online == Some(true) {
- return true;
- }
- }
- false
- }
-
- pub fn has_batteries(&self) -> bool {
- self.batteries().count() > 0
- }
-
- fn batteries(&self) -> impl Iterator<Item=&PowerSupplyInfo> {
- self.power_supplies
- .iter()
- .filter(|p| p.ty == PowerSupplyType::Battery)
- }
-
- fn mains(&self) -> impl Iterator<Item=&PowerSupplyInfo> {
- self.power_supplies
- .iter()
- .filter(|p| p.ty == PowerSupplyType::AC)
- }
-}
-
-impl PowerSupplyType {
- fn from_str(ty: &str) -> Self {
- match ty {
- "Mains" => PowerSupplyType::AC,
- "Battery" => PowerSupplyType::Battery,
- _ => panic!("unknown power supply type {}", ty),
- }
- }
-}
-
-fn slurp<T, U>(path: U) -> Option<T>
-where
- T: std::str::FromStr,
- U: AsRef<std::path::Path>,
-{
- let mut contents = String::new();
- std::fs::File::open(path).ok().and_then(|mut fh| {
- fh.read_to_string(&mut contents)
- .ok()
- .and_then(|_| contents.trim().parse().ok())
- })
-}
diff --git a/src/power/mod.rs b/src/power/mod.rs
new file mode 100644
index 0000000..afe5194
--- /dev/null
+++ b/src/power/mod.rs
@@ -0,0 +1,86 @@
+use std;
+
+use std::io::Read;
+
+mod sys;
+
+// XXX maybe extract this out into a separate crate?
+
+#[derive(Debug)]
+pub struct PowerInfo {
+ power_supplies: Vec<sys::PowerSupplyInfo>,
+}
+
+impl PowerInfo {
+ pub fn new() -> PowerInfo {
+ let power_supplies = sys::power_supplies();
+
+ PowerInfo {
+ power_supplies,
+ }
+ }
+
+ pub fn battery_usage(&self) -> Option<f64> {
+ let mut total_now = 0;
+ let mut total_full = 0;
+ for battery in self.batteries() {
+ if let Some(now) = battery.energy_now {
+ total_now += now;
+ }
+ else {
+ return None;
+ }
+ if let Some(full) = battery.energy_full {
+ total_full += full;
+ }
+ else {
+ return None;
+ }
+ }
+
+ if total_full > 0 {
+ Some((total_now as f64) / (total_full as f64))
+ }
+ else {
+ None
+ }
+ }
+
+ pub fn charging(&self) -> bool {
+ for mains in self.mains() {
+ if mains.online == Some(true) {
+ return true;
+ }
+ }
+ false
+ }
+
+ pub fn has_batteries(&self) -> bool {
+ self.batteries().count() > 0
+ }
+
+ fn batteries(&self) -> impl Iterator<Item=&sys::PowerSupplyInfo> {
+ self.power_supplies
+ .iter()
+ .filter(|p| p.ty == sys::PowerSupplyType::Battery)
+ }
+
+ fn mains(&self) -> impl Iterator<Item=&sys::PowerSupplyInfo> {
+ self.power_supplies
+ .iter()
+ .filter(|p| p.ty == sys::PowerSupplyType::AC)
+ }
+}
+
+fn slurp<T, U>(path: U) -> Option<T>
+where
+ T: std::str::FromStr,
+ U: AsRef<std::path::Path>,
+{
+ let mut contents = String::new();
+ std::fs::File::open(path).ok().and_then(|mut fh| {
+ fh.read_to_string(&mut contents)
+ .ok()
+ .and_then(|_| contents.trim().parse().ok())
+ })
+}
diff --git a/src/power/sys/linux.rs b/src/power/sys/linux.rs
new file mode 100644
index 0000000..670498a
--- /dev/null
+++ b/src/power/sys/linux.rs
@@ -0,0 +1,45 @@
+use walkdir;
+
+pub fn power_supplies() -> Vec<super::PowerSupplyInfo> {
+ let mut power_supplies = vec![];
+ for entry in walkdir::WalkDir::new("/sys/class/power_supply/")
+ .min_depth(1)
+ .max_depth(1)
+ .follow_links(true)
+ {
+ let entry = entry.unwrap();
+
+ let name = entry
+ .path()
+ .file_name()
+ .unwrap()
+ .to_string_lossy()
+ .into_owned();
+ let ty = super::super::slurp(entry.path().join("type"))
+ .map(|t: String| super::PowerSupplyType::from_str(&t))
+ .expect("couldn't find power supply type");
+ let energy_full = super::super::slurp(entry.path().join("energy_full"));
+ let energy_now = super::super::slurp(entry.path().join("energy_now"));
+ let online =
+ super::super::slurp(entry.path().join("online")).map(|n: u8| n != 0);
+
+ power_supplies.push(super::PowerSupplyInfo {
+ name,
+ ty,
+ energy_now,
+ energy_full,
+ online,
+ })
+ }
+ power_supplies
+}
+
+impl super::PowerSupplyType {
+ fn from_str(ty: &str) -> Self {
+ match ty {
+ "Mains" => super::PowerSupplyType::AC,
+ "Battery" => super::PowerSupplyType::Battery,
+ _ => panic!("unknown power supply type {}", ty),
+ }
+ }
+}
diff --git a/src/power/sys/macos.rs b/src/power/sys/macos.rs
new file mode 100644
index 0000000..a0455ac
--- /dev/null
+++ b/src/power/sys/macos.rs
@@ -0,0 +1,3 @@
+pub fn power_supplies() -> Vec<super::PowerSupplyInfo> {
+ vec![]
+}
diff --git a/src/power/sys/mod.rs b/src/power/sys/mod.rs
new file mode 100644
index 0000000..b6bb469
--- /dev/null
+++ b/src/power/sys/mod.rs
@@ -0,0 +1,24 @@
+#[cfg(target_os = "linux")]
+mod linux;
+#[cfg(target_os = "linux")]
+pub use self::linux::*;
+
+#[cfg(target_os = "macos")]
+mod macos;
+#[cfg(target_os = "macos")]
+pub use self::macos::*;
+
+#[derive(PartialEq, Eq, Debug, Clone)]
+pub enum PowerSupplyType {
+ AC,
+ Battery,
+}
+
+#[derive(Debug, Clone)]
+pub struct PowerSupplyInfo {
+ pub name: String,
+ pub ty: PowerSupplyType,
+ pub energy_now: Option<u64>,
+ pub energy_full: Option<u64>,
+ pub online: Option<bool>,
+}