#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DeviceError {
InitFailed,
}
pub trait DeviceDriver {
fn name(&self) -> &'static str;
fn init(&mut self) -> Result<(), DeviceError>;
}
pub struct DeviceRegistry<'a> {
devices: &'a mut [Option<&'a mut dyn DeviceDriver>],
count: usize,
}
impl<'a> DeviceRegistry<'a> {
pub fn new(storage: &'a mut [Option<&'a mut dyn DeviceDriver>]) -> Self {
Self {
devices: storage,
count: 0,
}
}
pub fn len(&self) -> usize {
self.count
}
pub fn is_empty(&self) -> bool {
self.count == 0
}
pub fn register(&mut self, device: &'a mut dyn DeviceDriver) -> bool {
if self.count >= self.devices.len() {
return false;
}
self.devices[self.count] = Some(device);
self.count += 1;
true
}
pub fn init_all(&mut self) -> Result<(), DeviceError> {
for index in 0..self.count {
if let Some(device) = &mut self.devices[index] {
device.init()?;
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::{DeviceDriver, DeviceError, DeviceRegistry};
struct GoodDevice {
initialised: bool,
}
impl GoodDevice {
fn new() -> Self {
Self { initialised: false }
}
}
impl DeviceDriver for GoodDevice {
fn name(&self) -> &'static str {
"good"
}
fn init(&mut self) -> Result<(), DeviceError> {
self.initialised = true;
Ok(())
}
}
struct BadDevice;
impl DeviceDriver for BadDevice {
fn name(&self) -> &'static str {
"bad"
}
fn init(&mut self) -> Result<(), DeviceError> {
Err(DeviceError::InitFailed)
}
}
#[test]
fn register_and_init_devices() {
let mut good = GoodDevice::new();
let mut bad = BadDevice;
let mut storage: [Option<&mut dyn DeviceDriver>; 2] = [None, None];
let mut registry = DeviceRegistry::new(&mut storage);
assert!(registry.register(&mut good));
assert!(registry.register(&mut bad));
assert_eq!(registry.len(), 2);
let result = registry.init_all();
assert!(result.is_err());
}
}