summaryrefslogtreecommitdiff
path: root/ebus-rust/src/model/mod.rs
blob: fd738fa74dc5274b1fa693f684ca23bd232694f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use serde::Deserialize;

use quick_xml::de::{from_reader};

pub fn read_config(xml: &[u8]) -> Result<Ebus, String> {
    let ebus_configuration = from_reader(xml).map_err(|e| format!("failed to read xml: {}", e))?;
    Ok(ebus_configuration)
}

#[derive(Debug, Deserialize, PartialEq)]
pub struct Description {
    pub lang: String,
    #[serde(rename = "$value")]
    pub text: String,
}

#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum DeviceType {
    Master,
    Slave,
    Broadcast,
}

#[derive(Debug, Deserialize, PartialEq)]
pub struct Device {
    pub address: u8,
    #[serde(rename = "type", default)]
    pub device_type: Option<DeviceType>,
    pub name: String,
    #[serde(rename = "description", default)]
    pub descriptions: Vec<Description>,
}

#[derive(Debug, Deserialize, PartialEq)]
pub struct Devices {
    #[serde(rename = "device", default)]
    pub devices: Vec<Device>,
}

#[derive(Debug, Deserialize, PartialEq, Clone)]
pub struct ByteEnumOption {
    pub value: u8,
    pub name: String,
}

#[derive(Debug, Deserialize, PartialEq, Clone)]
pub struct ByteEnumList(pub Vec<ByteEnumOption>);

impl ByteEnumList {
    pub fn get(&self, value: u8) -> Option<String> {
        self.0
            .iter()
            .find(|v| v.value == value)
            .map(|v| v.name.clone())
    }
}

#[derive(Debug, Deserialize, PartialEq, Clone)]
pub enum PacketField {
    #[serde(rename = "byte")]
    Byte { offset: u8, name: String },
    #[serde(rename = "data1b")]
    Data1b { offset: u8, name: String },
    #[serde(rename = "data1c")]
    Data1c { offset: u8, name: String },
    #[serde(rename = "data2b")]
    Data2b { offset: u8, name: String },
    #[serde(rename = "data2c")]
    Data2c { offset: u8, name: String },
    #[serde(rename = "byteEnum")]
    ByteEnum {
        offset: u8,
        name: String,
        #[serde(rename = "option")]
        options: ByteEnumList,
    },
    #[serde(rename = "bcd")]
    Bcd { offset: u8, name: String },
    #[serde(rename = "bit")]
    Bit { offset: u8, name: String },
    #[serde(rename = "word")]
    Word { offset: u8, name: String },
    #[serde(rename = "string")]
    String {
        offset: u8,
        name: String,
        length: u8,
    },
}

#[derive(Debug, Deserialize, PartialEq)]
pub struct PacketFields {
    #[serde(rename = "$value")]
    pub fields: Option<Vec<PacketField>>,
}

#[derive(Debug, Deserialize, PartialEq)]
pub struct Packet {
    pub primary: u8,
    pub secondary: u8,
    pub name: String,
    #[serde(rename = "description", default)]
    pub descriptions: Vec<Description>,
    pub fields: PacketFields,
}

#[derive(Debug, Deserialize, PartialEq)]
pub struct Packets {
    #[serde(rename = "packet", default)]
    pub packets: Vec<Packet>,
}

impl Packets {
    pub fn get(&self, primary: u8, secondary: u8) -> Option<&Packet> {
        self.packets
            .iter()
            .find(|p| p.primary == primary && p.secondary == secondary)
    }
}

#[derive(Debug, Deserialize, PartialEq)]
pub struct Ebus {
    pub devices: Devices,
    pub packets: Packets,
}