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");
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"));
}
#[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);
}
}