stm32builder/
device.rs

1//! Device module
2
3use crate::{
4    api::{Convertible, Error},
5    device_info::{DeviceInfoIn, DeviceInfoOut, DevicePartIn},
6    peripherals::{PeripheralsIn, PeripheralsOut},
7    types::DeviceId,
8};
9use serde_derive::{Deserialize, Serialize};
10use std::fs::File;
11
12/// The input device.
13#[derive(Debug, Deserialize)]
14pub struct DeviceIn {
15    /// The device name this device file is for.
16    pub name: String,
17    /// The device common information.
18    pub info: DeviceInfoIn,
19    /// The available parts under this device name.
20    pub parts: Vec<DevicePartIn>,
21    /// The device peripherals.
22    pub peripherals: PeripheralsIn,
23}
24
25/// The output device.
26#[derive(Debug, Serialize)]
27pub struct DeviceOut {
28    /// This device information.
29    pub info: DeviceInfoOut,
30    /// The device peripherals.
31    pub peripherals: PeripheralsOut,
32}
33
34impl Convertible for DeviceIn {
35    type Output = DeviceOut;
36
37    /// Convert to outputable device.
38    fn to_output(&self, id: &DeviceId, device: &DeviceIn) -> DeviceOut {
39        DeviceOut {
40            info: self.info.to_output(&id, &device),
41            peripherals: self.peripherals.to_output(&id, &device),
42        }
43    }
44}
45
46impl DeviceIn {
47    /// Get a device input from a file
48    pub fn from_file(device: &File) -> Result<DeviceIn, Error> {
49        serde_yaml::from_reader(device).map_err(|e| Error::ParseError(e))
50    }
51}
52
53/// An stm32 device.
54// NOTE: It is our user facing entry point.
55pub struct Device;
56impl Device {
57    /// Get a device from its device file (if the id match the `name` key on the device).
58    pub fn from_id_and_file(id: &DeviceId, device: &File) -> Result<DeviceOut, Error> {
59        let device = DeviceIn::from_file(&device)?;
60
61        if id.name() != device.name {
62            return Err(Error::NoMatchFound);
63        }
64
65        Ok(device.to_output(&id, &device))
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::tests::*;
73
74    fn device_under_test() -> DeviceOut {
75        valid_device_in().to_output(&valid_device_id(), &valid_device_in())
76    }
77
78    #[test]
79    fn output_device_informations() {
80        assert_eq!(device_under_test().info, expected_device_info_out())
81    }
82    #[test]
83    fn created_from_id_and_file() {
84        let device = File::open("tests/stm32f051.yaml").unwrap();
85        let id = DeviceId::from_str("stm32f051R8T6").unwrap();
86
87        let device = Device::from_id_and_file(&id, &device).unwrap();
88
89        assert_eq!(device.info, expected_device_info_out());
90    }
91
92    #[test]
93    fn has_some_peripherals() {
94        assert_eq!(device_under_test().peripherals, expected_peripherals());
95    }
96}