reda-lib 0.5.0

Liberty file library
Documentation
use crate::error::{LibErrorContext, LibError};
use crate::model::{LibAst, LibCell, LibGroup, LibLibrary};

use super::FromLibGroup;

impl LibLibrary {
    pub fn from_ast(ast: LibAst) -> Result<Self, LibError> {
        let group = LibGroup::from_ast(ast).context(|| "semantic root ast to group")?;
        Self::from_group(group)
    }
}

impl FromLibGroup for LibLibrary {
    type Error = LibError;
    fn  from_group(group: LibGroup) -> Result<Self, LibError> {
        let mut group = group;
        let name = group.expect_name().context(|| "group name")?;
        let (cell_groups, groups) = group.groups.into_iter().partition(|g| g.kind == "cell");
        
        // collect cells
        let mut cells = Vec::new();
        for cell_group in cell_groups {
            cells.push(LibCell::from_group(cell_group).context(|| "semantic cell")?);
        }

        Ok(Self {
            name,
            attrs: group.attrs,
            groups,
            cells,
        })
    }
}

#[cfg(test)]
mod test {
    use super::*;


    #[test]
    fn test_cell_from_group() {
        let mut group = LibGroup::new("cell", vec!["AND2".to_string()]);
        group.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
        group.groups.push(LibGroup::new("pin", vec!["a".to_string()]));
        group.groups.push(LibGroup::new("pin", vec!["b".to_string()]));
        let cell = LibCell::from_group(group).unwrap();
        assert_eq!(cell.name, "AND2");
        assert_eq!(cell.groups.len(), 1);
        assert_eq!(cell.pins.len(), 2);
    }

    #[test]
    fn test_library_into_group() {
        let mut lib = LibLibrary::new("my_lib");
        lib.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
        lib.cells.push(LibCell::new("AND2"));
        lib.cells.push(LibCell::new("NAND2"));
        // let group = lib.into_group();
        // assert_eq!(group.type_, "library");
        // assert_eq!(group.name, "my_lib");
        // assert_eq!(group.groups.len(), 3);
    }

    #[test]
    fn test_lib_from_group() {
        let mut group = LibGroup::new("library", vec!["mylib".to_string()]);
        group.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
        let mut cell = LibGroup::new("cell", vec!["AND2".to_string()]);
        cell.groups.push(LibGroup::new("pin", vec!["a".to_string()]));
        cell.groups.push(LibGroup::new("pin", vec!["b".to_string()]));
        group.groups.push(cell);
        let lib = LibLibrary::from_group(group).unwrap();
        assert_eq!(lib.name, "mylib");
        assert_eq!(lib.groups.len(), 1);
        assert_eq!(lib.cells.len(), 1);
        let converted_cell = lib.cell("AND2").unwrap();
        assert_eq!(converted_cell.name, "AND2");
        assert_eq!(converted_cell.groups.len(), 0);
        assert_eq!(converted_cell.pins.len(), 2);
    }
}