#![allow(non_snake_case, clippy::unreadable_literal)]
use std::default::Default;
use std::mem;
use std::ops;
use std::str::{self, FromStr};
use crate::Technology;
use winapi::shared::ntdef;
pub const BATTERY_CAPACITY_RELATIVE: ntdef::ULONG = 0x40000000;
pub const BATTERY_SYSTEM_BATTERY: ntdef::ULONG = 0x80000000;
STRUCT! {#[cfg_attr(target_arch = "x86", repr(packed))] #[derive(Debug)] struct BATTERY_INFORMATION {
Capabilities: ntdef::ULONG,
Technology: ntdef::UCHAR,
Reserved: [ntdef::UCHAR; 3],
Chemistry: [ntdef::UCHAR; 4],
DesignedCapacity: ntdef::ULONG, FullChargedCapacity: ntdef::ULONG, DefaultAlert1: ntdef::ULONG,
DefaultAlert2: ntdef::ULONG,
CriticalBias: ntdef::ULONG,
CycleCount: ntdef::ULONG,
}}
impl Default for BATTERY_INFORMATION {
#[inline]
fn default() -> Self {
unsafe { mem::zeroed() }
}
}
#[derive(Debug)]
pub struct BatteryInformation(BATTERY_INFORMATION);
impl Default for BatteryInformation {
fn default() -> Self {
BatteryInformation(BATTERY_INFORMATION::default())
}
}
impl ops::Deref for BatteryInformation {
type Target = BATTERY_INFORMATION;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl ops::DerefMut for BatteryInformation {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl BatteryInformation {
#[inline]
pub fn is_system_battery(&self) -> bool {
(self.0.Capabilities & BATTERY_SYSTEM_BATTERY) != 0
}
#[inline]
pub fn is_relative(&self) -> bool {
(self.0.Capabilities & BATTERY_CAPACITY_RELATIVE) != 0
}
pub fn technology(&self) -> Technology {
let raw = unsafe { str::from_utf8_unchecked(&self.0.Chemistry) };
match Technology::from_str(raw) {
Ok(tech) => tech,
Err(_) => Technology::Unknown,
}
}
#[inline]
pub fn designed_capacity(&self) -> u32 {
self.0.DesignedCapacity
}
#[inline]
pub fn full_charged_capacity(&self) -> u32 {
self.0.FullChargedCapacity
}
pub fn cycle_count(&self) -> Option<u32> {
if self.0.CycleCount == 0 {
None
} else {
Some(self.0.CycleCount)
}
}
}