1mod ast;
2mod library;
3mod cell;
4mod pin;
5pub use ast::*;
6pub use library::*;
7pub use cell::*;
8pub use pin::*;
9
10use std::collections::HashMap;
11use crate::error::LibError;
12
13pub trait Model {
14 fn attrs(&self) -> &HashMap<String, LibValue>;
15 fn groups(&self) -> &[LibGroup];
16 fn attr(&self, name: &str) -> Option<&LibValue> {
17 self.attrs().get(name)
18 }
19 fn kind_groups(&self, kind: &str) -> impl IntoIterator<Item = &LibGroup> {
20 self.groups().into_iter().filter(move |g| g.kind == kind)
21 }
22}
23
24#[derive(Debug, PartialEq, Clone, Default)]
25pub struct LibGroup {
26 pub kind: String,
27 pub params: Vec<String>,
28
29 pub attrs: HashMap<String, LibValue>,
30 pub groups: Vec<LibGroup>,
31}
32
33impl LibGroup {
34 pub fn new<S: Into<String>, P: Into<Vec<String>>>(kind: S, params: P) -> Self {
35 Self {
36 kind: kind.into(),
37 params: params.into(),
38 ..Default::default()
39 }
40 }
41}
42
43impl Model for LibGroup {
44 fn attrs(&self) -> &HashMap<String, LibValue> {
45 &self.attrs
46 }
47
48 fn groups(&self) -> &[LibGroup] {
49 &self.groups
50 }
51}
52
53impl LibGroup {
54 pub fn expect_name(&mut self) -> Result<String, LibError> {
55 if self.params.len() != 1 {
56 Err(LibError::LibraryParamLenUnmatch)?
57 }
58 Ok(self.params[0].clone())
59 }
60
61 pub fn expect_ident_attr(&mut self, attr_name: &str) -> Result<String, LibError> {
62 if let Some(value) = self.attrs.remove(attr_name) {
63 let s = value.into_ident()?;
64 Ok(s)
65 } else {
66 Err(LibError::MissAttr(attr_name.to_string()))
67 }
68 }
69
70 pub fn expect_ident_attr_opt(&mut self, attr_name: &str) -> Result<Option<String>, LibError> {
71 if let Some(value) = self.attrs.remove(attr_name) {
72 let s = value.into_ident()?;
73 Ok(Some(s))
74 } else {
75 Ok(None)
76 }
77 }
78
79 pub fn expect_string_attr_opt(&mut self, attr_name: &str) -> Result<Option<String>, LibError> {
80 if let Some(value) = self.attrs.remove(attr_name) {
81 let s = value.into_string()?;
82 Ok(Some(s))
83 } else {
84 Ok(None)
85 }
86 }
87}
88
89#[cfg(test)]
90mod test {
91 use super::*;
92
93 #[test]
94 fn test_cells() {
95 let lib = LibLibrary::load_file("./data/cells.lib").unwrap();
96 let and2 = lib.cell("AND2").unwrap();
97 let pin = and2.pin("o").unwrap();
98 println!("{:#?}", pin.function);
99 }
100}