mod dmx;
use std::collections::HashMap;
use crate::schema::{DeviceClass, EstaDmx, Parameter};
use crate::{e173_types, Error};
pub use dmx::{DmxDriver, ParamRange, ParameterCombo, ParameterConstraint};
e173_types! {
#[serde(rename_all = "camelCase")]
pub struct ParameterDatabase {
pub parameters: HashMap<String, Parameter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dmx_driver: Option<DmxDriver>,
}
}
pub fn create_parameter_database(device_class: &DeviceClass) -> Result<ParameterDatabase, Error> {
let parameters = device_class.parameters.clone();
let dmx = get_dmx_serializer(device_class)?;
let dmx_driver = match dmx {
Some(dmx) => {
let driver = DmxDriver::from(&dmx)?;
if driver.chunks.is_empty() && driver.clusters.is_empty() {
None
} else {
Some(driver)
}
}
None => None,
};
Ok(ParameterDatabase {
parameters,
dmx_driver,
})
}
fn get_dmx_serializer(device_class: &DeviceClass) -> Result<Option<EstaDmx>, Error> {
let mut ser_iter = device_class.serializers.iter().filter(|(_, ser)| {
matches!(ser.library.as_deref(), Some("org.esta.lib.core")) && ser.class == "esta-dmx"
});
let Some(serializer) = ser_iter.next().map(|(_, ser)| ser) else {
return Ok(None);
};
if let Some((key, _)) = ser_iter.next() {
return Err(Error::invalid_device_class(
"Device class contains multiple ESTA DMX serializers",
format!("/serializers/{key}"),
));
}
let Some(default_val) = &serializer.default else {
return Ok(None);
};
serde_json::from_value(default_val.clone())
.map(Some)
.map_err(Error::dmx_parse)
}