rdrive/
manager.rs

1use alloc::{collections::btree_map::BTreeMap, vec::Vec};
2
3use rdif_base::DriverGeneric;
4
5use crate::{
6    Descriptor, Device, DeviceId, DeviceOwner, GetDeviceError,
7    error::DriverError,
8    probe::ProbeError,
9    register::{DriverRegister, RegisterContainer},
10};
11
12pub struct Manager {
13    pub registers: RegisterContainer,
14    pub(crate) dev_container: DeviceContainer,
15    // pub(crate) enum_system: EnumSystem,
16}
17
18impl Manager {
19    pub fn new() -> Result<Self, DriverError> {
20        Ok(Self {
21            // enum_system: EnumSystem::new(platform)?,
22            registers: RegisterContainer::default(),
23            dev_container: DeviceContainer::default(),
24        })
25    }
26
27    pub fn unregistered(&mut self) -> Result<Vec<DriverRegister>, ProbeError> {
28        let mut out = self.registers.unregistered();
29        out.sort_by(|a, b| a.priority.cmp(&b.priority));
30        Ok(out)
31    }
32}
33
34#[derive(Default)]
35pub(crate) struct DeviceContainer {
36    devices: BTreeMap<DeviceId, DeviceOwner>,
37}
38
39impl DeviceContainer {
40    pub fn insert<T: DriverGeneric>(&mut self, descriptor: Descriptor, device: T) {
41        self.devices
42            .insert(descriptor.device_id, DeviceOwner::new(descriptor, device));
43    }
44
45    pub fn get_typed<T: DriverGeneric>(&self, id: DeviceId) -> Result<Device<T>, GetDeviceError> {
46        let dev = self.devices.get(&id).ok_or(GetDeviceError::NotFound)?;
47
48        dev.weak()
49    }
50
51    pub fn get_one<T: DriverGeneric>(&self) -> Option<Device<T>> {
52        for dev in self.devices.values() {
53            if let Ok(val) = dev.weak::<T>() {
54                return Some(val);
55            }
56        }
57        None
58    }
59
60    pub fn devices<T: DriverGeneric>(&self) -> Vec<Device<T>> {
61        let mut result = Vec::new();
62        for dev in self.devices.values() {
63            if let Ok(val) = dev.weak::<T>() {
64                result.push(val);
65            }
66        }
67        result
68    }
69}
70
71#[cfg(test)]
72mod tests {
73
74    use crate::driver::{DriverGeneric, Empty};
75    use rdif_intc::*;
76
77    use super::*;
78
79    struct DeviceTest {
80        opened: bool,
81    }
82
83    impl DriverGeneric for DeviceTest {
84        fn open(&mut self) -> Result<(), rdif_base::KError> {
85            self.opened = true;
86            Ok(())
87        }
88
89        fn close(&mut self) -> Result<(), rdif_base::KError> {
90            if !self.opened {
91                panic!("Device not opened before closing");
92            }
93            self.opened = false;
94            Ok(())
95        }
96    }
97
98    #[test]
99    fn test_device_container() {
100        let mut container = DeviceContainer::default();
101        let desc = Descriptor::new();
102        let id = desc.device_id;
103        container.insert(desc, Empty);
104        let weak = container.get_typed::<Empty>(id).unwrap();
105
106        {
107            let mut device = weak.lock().unwrap();
108
109            assert!(device.open().is_ok());
110            assert!(device.close().is_ok());
111        }
112
113        {
114            let mut device = weak.lock().unwrap();
115
116            assert!(device.open().is_ok());
117            assert!(device.close().is_ok());
118        }
119    }
120    #[test]
121    fn test_get_one() {
122        let mut container = DeviceContainer::default();
123        container.insert(Descriptor::new(), Empty);
124        container.insert(Descriptor::new(), DeviceTest { opened: false });
125
126        let weak = container.get_one::<Empty>().unwrap();
127        {
128            let mut device = weak.lock().unwrap();
129            assert!(device.open().is_ok());
130            assert!(device.close().is_ok());
131        }
132    }
133
134    #[test]
135    fn test_devices() {
136        let mut container = DeviceContainer::default();
137        container.insert(Descriptor::new(), Empty);
138        container.insert(Descriptor::new(), Empty);
139        container.insert(Descriptor::new(), DeviceTest { opened: false });
140        let devices = container.devices::<Empty>();
141        assert_eq!(devices.len(), 2);
142    }
143
144    #[test]
145    fn test_not_found() {
146        let container = DeviceContainer::default();
147        let dev = container.get_one::<Intc>();
148        assert!(dev.is_none(), "Expected no devices found");
149
150        if let Some(dev) = dev {
151            let weak = dev.lock().unwrap();
152            let f = weak.parse_dtb_fn();
153            assert!(f.is_none(), "Expected no parse function for empty device");
154        }
155    }
156
157    struct IrqTest {}
158
159    impl IrqTest {
160        fn is_ok(&mut self) -> bool {
161            true // Placeholder for actual logic
162        }
163    }
164
165    impl crate::DriverGeneric for IrqTest {
166        fn open(&mut self) -> Result<(), KError> {
167            Ok(())
168        }
169
170        fn close(&mut self) -> Result<(), KError> {
171            Ok(())
172        }
173    }
174
175    impl Interface for IrqTest {}
176
177    #[test]
178    fn test_inner_type() {
179        let mut container = DeviceContainer::default();
180        let desc = Descriptor::new();
181        container.insert(desc, Intc::new(IrqTest {}));
182
183        let weak = container.get_one::<Intc>().unwrap();
184        {
185            let device = weak.lock().unwrap();
186            let intc = device.typed_ref::<IrqTest>();
187            assert!(intc.is_some(), "Expected to find IrqTest device");
188        }
189    }
190
191    #[test]
192    fn test_device_downcast() {
193        let mut container = DeviceContainer::default();
194        let desc = Descriptor::new();
195        container.insert(desc, Intc::new(IrqTest {}));
196
197        let weak = container.get_one::<Intc>().unwrap();
198        let intc_typed = weak.downcast::<IrqTest>().unwrap();
199        let mut device = intc_typed.lock().unwrap();
200        assert!(device.is_ok(), "Expected device to be ok");
201    }
202
203    #[test]
204    fn test_locked_device() {
205        let mut container = DeviceContainer::default();
206        let desc = Descriptor::new();
207        let id = desc.device_id;
208        container.insert(desc, Empty);
209
210        let weak = container.get_typed::<Empty>(id).unwrap();
211        let device = weak.lock().unwrap();
212        let r = weak.try_lock();
213        assert!(
214            r.is_err(),
215            "Expected error when trying to lock an already locked device"
216        );
217        let _ = device;
218    }
219}