use crate::types::{
attributes::{AttrValueType, AttributeSpec, AttributeValue},
database::CanDatabase,
};
pub(crate) fn decode(db: &mut CanDatabase, line: &str) {
let mut parts = line.trim_end_matches(';').split_ascii_whitespace();
match parts.next() {
Some("BA_") => {}
_ => return,
}
let attr_tok: &str = match parts.next() {
Some(a) => a,
None => return,
};
let attr_name: &str = attr_tok.trim_matches('"');
match parts.next() {
Some("BO_") => {}
_ => return,
}
let Some(msg_id_tok) = parts.next() else {
return;
};
let Ok(msg_id) = msg_id_tok.parse::<u32>() else {
return;
};
let rest_joined: String = parts.collect::<Vec<_>>().join(" ");
let rest: &str = rest_joined.trim();
let value: &str = if let Some(inner) = rest.strip_prefix('"') {
match inner.find('"') {
Some(end) => &inner[..end],
None => return, }
} else {
rest
};
let attr_spec: &AttributeSpec = match db.attr_spec.get(attr_name) {
Some(spec) => spec,
None => return, };
let attr_value: AttributeValue = match attr_spec.value_type {
AttrValueType::String => AttributeValue::Str(value.to_string()),
AttrValueType::Int => {
let Ok(num) = value.parse::<i64>() else {
return;
};
AttributeValue::Int(num)
}
AttrValueType::Hex => {
let Ok(num) = value.parse::<u64>() else {
return;
};
AttributeValue::Hex(num)
}
AttrValueType::Float => {
let Ok(num) = value.parse::<f64>() else {
return;
};
AttributeValue::Float(num)
}
AttrValueType::Enum => {
let Ok(idx) = value.parse::<usize>() else {
return;
};
let Some(v) = attr_spec.enum_values.get(idx) else {
return;
};
AttributeValue::Enum(v.clone())
}
};
if let Some(msg) = db.get_message_by_id_mut(msg_id)
&& let Some(slot) = msg.attributes.get_mut(attr_name)
{
*slot = attr_value;
}
}