Battery Iterators
Relevant source files
The following files were used as context for generating this wiki page:
Battery Iterators provide a unified, cross-platform mechanism for discovering and accessing multiple battery devices connected to a system. Within the rust-battery crate, these iterators abstract away OS-specific device enumeration (such as Linux SysFS, macOS IOKit, or Windows IOCTL) into a standard Rust Iterator interface.
The primary entry point for obtaining an iterator is the Manager::batteries() method, which yields a Batteries struct. This struct iterates over Result<Battery> items, allowing developers to handle potential OS errors during the discovery process for each individual device.
Sources: src/types/manager.rs:43-47, src/types/iterator.rs:13-16, src/lib.rs:36
Architecture and Traits
The iterator system is built on a trait-based abstraction layer that separates high-level public types from platform-specific implementations.
The BatteryIterator Trait
Every platform must implement the BatteryIterator trait. This trait requires the iterator to be associated with a specific BatteryManager and a BatteryDevice. Crucially, the trait dictates that the next() implementation must preload all necessary battery data, as the subsequent BatteryDevice methods are designed to be infallible.
Sources: src/platform/traits.rs:21-32
Component Relationship
The following diagram illustrates the relationship between the public Batteries iterator and the underlying platform-specific traits.
The public Batteries struct acts as a wrapper around a PlatformIterator (a type alias for the current OS implementation), providing a consistent API regardless of the target platform.
Sources: src/types/iterator.rs:13-33, src/platform/traits.rs:21-25
Data Flow and Lifetime
Battery Iterators are tightly coupled with the Manager that created them. The BatteryIterator trait requires that the iterator instance stores a reference to its parent Manager. This ensures that all iterator instances are freed before the manager itself is dropped, preventing use-after-free scenarios in platform-specific FFI calls.
Sequence of Battery Discovery
The following sequence shows how a user interacts with the API to iterate over system batteries.
Implementation Details
Iterator Characteristics
The Batteries iterator is marked with #[must_use], reminding developers that iterators in Rust are lazy and perform no work unless consumed.
| Feature | Description |
|---|---|
| Ordering | No guarantees are provided for battery ordering; order depends on the underlying OS implementation. |
| Error Handling | Each iteration returns a Result<Battery>, allowing the iterator to continue even if one device fails to load. |
| Laziness | The iterator is lazy; OS resources are queried only as next() is called. |
| Lifetime Management | Iterators hold an Arc to the Manager to ensure safe resource cleanup. |
Sources: src/types/iterator.rs:12-16, src/types/manager.rs:43-46, src/platform/traits.rs:32
Platform Example: Windows Discovery
On Windows, the iterator implementation (within DeviceIterator) utilizes setupapi to enumerate device interfaces under the GUID_DEVCLASS_BATTERY class. For each device found, it opens a file handle and queries a "Battery Tag," which is then used for subsequent IOCTL calls to fetch hardware data.
Sources: src/platform/windows/ffi/mod.rs:31-48, src/platform/windows/ffi/mod.rs:141-152
Usage in Code
The iterator is typically used in a for loop or with standard iterator adaptors.
// Example of consuming the battery iterator
let manager = Manager::new()?;
let batteries = manager.batteries()?;
for maybe_battery in batteries {
let battery = maybe_battery?; // Handle potential IO error
println!("Found battery: {:?}", battery.model());
}
Sources: src/types/manager.rs:16-20, examples/simple.rs:9-20
Summary
Battery Iterators serve as the bridge between platform-specific device enumeration and the high-level Battery API. By enforcing data preloading in the next() method and maintaining strict lifetime associations with the Manager, the system ensures that battery data access is both safe and efficient across different operating systems.