use espf::context::ParsedNode;
use espf::diag::EspfError;
use espforge_bindings::components::attrs::Issue;
use espforge_bindings::components::generated_elements::uart as schema;
#[derive(Debug, Clone)]
pub struct UartPeripheral {
pub id: String,
pub peripheral: String,
pub tx: u8,
pub rx: u8,
}
pub fn uart_peripheral_name(n: &ParsedNode) -> Result<String, EspfError> {
let id = n.id;
if matches!(id, "uart0" | "uart1" | "uart2" | "uart3") {
return Ok(id.to_ascii_uppercase());
}
Err(EspfError::at_node(
n,
"invalid uart id",
format!(
"<uart id=\"{id}\">: the id must be uart0, uart1, uart2 or uart3 (or give uart=\"UART1\" explicitly)"
),
))
}
pub fn uart_attr_peripheral(n: &ParsedNode, raw: &str) -> Result<String, EspfError> {
let upper = raw.trim().to_ascii_uppercase();
if matches!(upper.as_str(), "UART0" | "UART1" | "UART2" | "UART3") {
return Ok(upper);
}
Err(EspfError::at_node(
n,
"invalid uart peripheral",
format!(
"<uart id=\"{}\"> uart=\"{raw}\" must be UART0, UART1, UART2 or UART3",
n.id
),
))
}
pub fn lower_uart(n: &ParsedNode) -> Result<UartPeripheral, EspfError> {
let attrs = schema::Attrs::from_node(n)
.map_err(|issue| EspfError::at_node(n, "invalid uart pin", message(n.id, issue)))?;
let peripheral = match attrs.uart {
Some(raw) => uart_attr_peripheral(n, raw.value)?,
None => uart_peripheral_name(n)?,
};
Ok(UartPeripheral {
id: n.id.to_string(),
peripheral,
tx: attrs.tx.value,
rx: attrs.rx.value,
})
}
fn message(id: &str, issue: Issue<'_>) -> String {
match issue {
Issue::Missing { attr } | Issue::Invalid { attr, .. } => {
format!("<uart id=\"{id}\"> needs a numeric {attr}=\"...\"")
}
}
}