svd-generator 0.7.0

Converts device information from flattened device tree into an SVD description
Documentation
use crate::{Error, Result};

/// Parses the `interrupts` property.
///
/// # Parameters
///
/// - `node`: Device Tree node to parse
/// - `default_name`: default interrupt name (used if `interrupt-names` property is absent)
/// - `count`: optional peripheral count if more than one of its type exists
pub fn parse_interrupts<'b, 'a: 'b>(
    node: &fdt::node::FdtNode<'b, 'a>,
    default_name: &str,
    count: Option<usize>,
) -> Result<Vec<svd::Interrupt>> {
    let ints_prop = node
        .property("interrupts")
        .ok_or(Error::DeviceTree(format!(
            "{} missing `interrupts` property",
            node.name
        )))?;

    let ints = ints_prop.iter_cell_size(node.interrupt_cells().unwrap_or(1).into());

    // `interrupt-names` is an unspecified property as of v0.4, so it may not be present
    let int_names = node.property("interrupt-names").map(|p| p.iter_str());

    let mut i = 0;
    let def_int_names = core::iter::from_fn(move || {
        let num = i;
        i += 1;

        if num > 0 {
            Some(format!("{default_name}{num}"))
        } else {
            Some(default_name.into())
        }
    });

    let count_str = count.map(|c| format!("{c}")).unwrap_or_default();

    match int_names {
        Some(p) => Ok(ints
            .zip(p)
            .filter_map(|(int, name)| {
                svd::Interrupt::builder()
                    .name(format!("{}{count_str}", name.to_uppercase()))
                    .value(int as u32)
                    .build(svd::ValidateLevel::Strict)
                    .ok()
            })
            .collect()),
        None => Ok(ints
            .zip(def_int_names)
            .filter_map(|(int, name)| {
                svd::Interrupt::builder()
                    .name(format!("{}{count_str}", name.to_uppercase()))
                    .value(int as u32)
                    .build(svd::ValidateLevel::Strict)
                    .ok()
            })
            .collect()),
    }
}