Skip to main content

hap_model/
accessories.rs

1//! The `/accessories` response parser.
2
3use crate::error::Result;
4use crate::generated::{CharacteristicType, ServiceType};
5use crate::tree::{
6    Accessory, Characteristic, Service, WireAccessories, WireCharacteristic, WireService,
7};
8
9/// Parse the body of a `GET /accessories` response into the typed tree.
10///
11/// # Errors
12/// - [`crate::ModelError::Json`] if the bytes are not the expected JSON shape.
13/// - [`crate::ModelError::MalformedUuid`] for an unparseable `type`.
14/// - [`crate::ModelError::ValueType`] / [`crate::ModelError::ValueRange`] /
15///   [`crate::ModelError::Base64`] if a present `value` does not match its
16///   declared `format`.
17pub fn parse_accessories(json: &[u8]) -> Result<Vec<Accessory>> {
18    let wire: WireAccessories = serde_json::from_slice(json)?;
19    wire.accessories
20        .into_iter()
21        .map(|a| {
22            Ok(Accessory {
23                aid: a.aid,
24                services: a
25                    .services
26                    .into_iter()
27                    .map(convert_service)
28                    .collect::<Result<Vec<_>>>()?,
29            })
30        })
31        .collect()
32}
33
34fn convert_service(s: WireService) -> Result<Service> {
35    Ok(Service {
36        iid: s.iid,
37        service_type: ServiceType::from_uuid(&s.type_),
38        characteristics: s
39            .characteristics
40            .into_iter()
41            .map(convert_characteristic)
42            .collect::<Result<Vec<_>>>()?,
43    })
44}
45
46fn convert_characteristic(c: WireCharacteristic) -> Result<Characteristic> {
47    let value = match c.value {
48        Some(ref v) => Some(c.format.value_from_json(v)?),
49        None => None,
50    };
51    Ok(Characteristic {
52        iid: c.iid,
53        char_type: CharacteristicType::from_uuid(&c.type_),
54        format: c.format,
55        perms: c.perms,
56        value,
57        unit: c.unit,
58        min_value: c.min_value,
59        max_value: c.max_value,
60        min_step: c.min_step,
61        max_len: c.max_len,
62    })
63}