1mod ast;
2mod library;
3mod cell;
4mod pin;
5mod expr;
6pub use ast::*;
7pub use library::*;
8pub use cell::*;
9pub use pin::*;
10pub use expr::*;
11
12use std::{collections::HashMap, error::Error, str::FromStr};
13use crate::error::{LibError, LibErrorContext};
14
15pub trait Model {
16 fn attrs(&self) -> &HashMap<String, LibValue>;
17 fn groups(&self) -> &[LibGroup];
18 fn attr(&self, name: &str) -> Option<&LibValue> {
19 self.attrs().get(name)
20 }
21 fn attr_must(&self, name: &str) -> Result<&LibValue, LibError> {
22 self.attr(name).ok_or_else(|| LibError::MissAttr(name.to_string()))
23 }
24 fn kind_groups(&self, kind: &str) -> impl IntoIterator<Item = &LibGroup> {
25 self.groups().into_iter().filter(move |g| g.kind == kind)
26 }
27}
28
29#[derive(Debug, PartialEq, Clone, Default)]
30pub struct LibGroup {
31 pub kind: String,
32 pub params: Vec<String>,
33
34 pub attrs: HashMap<String, LibValue>,
35 pub groups: Vec<LibGroup>,
36}
37
38impl LibGroup {
39 pub fn new<S: Into<String>, P: Into<Vec<String>>>(kind: S, params: P) -> Self {
40 Self {
41 kind: kind.into(),
42 params: params.into(),
43 ..Default::default()
44 }
45 }
46}
47
48impl Model for LibGroup {
49 fn attrs(&self) -> &HashMap<String, LibValue> {
50 &self.attrs
51 }
52
53 fn groups(&self) -> &[LibGroup] {
54 &self.groups
55 }
56}
57
58impl LibGroup {
59 pub fn expect_name(&mut self) -> Result<String, LibError> {
60 if self.params.len() != 1 {
61 Err(LibError::LibraryParamLenUnmatch)?
62 }
63 Ok(self.params[0].clone())
64 }
65
66 pub fn attr_bool_opt<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<Option<bool>, LibError> {
67 match self.attr(attr_name) {
68 Some(v) => Ok(Some(v.bool().context(ctx)?)),
69 None => Ok(None),
70 }
71 }
72
73 pub fn attr_float_opt<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<Option<f64>, LibError> {
74 match self.attr(attr_name) {
75 Some(v) => Ok(Some(v.float().context(ctx)?)),
76 None => Ok(None),
77 }
78 }
79
80 pub fn attr_string_opt<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<Option<&str>, LibError> {
81 match self.attr(attr_name) {
82 Some(v) => Ok(Some(v.string().context(ctx)?)),
83 None => Ok(None),
84 }
85 }
86
87 pub fn attr_ident_opt<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<Option<&str>, LibError> {
88 match self.attr(attr_name) {
89 Some(v) => Ok(Some(v.ident().context(ctx)?)),
90 None => Ok(None),
91 }
92 }
93
94 pub fn attr_expr_opt<S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<Option<LibExpr>, LibError> {
95 match self.attr(attr_name) {
96 Some(v) => {
97 let s = v.string().context(ctx)?;
98 let expr = LibExpr::from_str(s).context(ctx)?;
99 Ok(Some(expr))
100 }
101 None => Ok(None),
102 }
103 }
104
105 pub fn attr_floats_opt<const N: usize, S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<Option<[f64; N]>, LibError> {
106 match self.attr(attr_name) {
107 Some(v) => {
108 let vs = v.vector().context(ctx)?;
109 if vs.len() != N {
110 Err(LibError::Parse(format!("expect float len {}, got {}", N, vs.len())))?;
111 }
112 let mut fs = [0.0; N];
113 for i in 0..N {
114 let v = &vs[i];
115 let f = v.float().context(ctx)?;
116 fs[i] = f;
117 }
118 Ok(Some(fs))
119 }
120 None => Ok(None),
121 }
122 }
123
124 pub fn attr_parse_opt<T, S, F>(&self, attr_name: &str, ctx: &F) -> Result<Option<T>, LibError>
125 where
126 T: FromStr,
127 T::Err: Error,
128 S: Into<String>,
129 F: Fn() -> S
130 {
131 match self.attr(attr_name) {
132 Some(v) => {
133 let s = v.ident().context(ctx)?;
134 let v = T::from_str(s).map_err(|e| LibError::Parse(e.to_string())).context(ctx)?;
135 Ok(Some(v))
136 }
137 None => Ok(None),
138 }
139 }
140
141 pub fn attr_bool<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<bool, LibError> {
142 let v = self.attr_bool_opt(attr_name, ctx)?;
143 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
144 }
145
146 pub fn attr_float<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<f64, LibError> {
147 let v = self.attr_float_opt(attr_name, ctx)?;
148 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
149 }
150
151 pub fn attr_string<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<&str, LibError> {
152 let v = self.attr_string_opt(attr_name, ctx)?;
153 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
154 }
155
156 pub fn attr_ident<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<&str, LibError> {
157 let v = self.attr_ident_opt(attr_name, ctx)?;
158 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
159 }
160
161 pub fn attr_expr<S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<LibExpr, LibError> {
162 let v = self.attr_expr_opt(attr_name, ctx)?;
163 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
164 }
165
166 pub fn attr_parse<T, S, F>(&self, attr_name: &str, ctx: &F) -> Result<T, LibError>
167 where
168 T: FromStr,
169 T::Err: Error,
170 S: Into<String>,
171 F: Fn() -> S
172 {
173 let v = self.attr_parse_opt(attr_name, ctx)?;
174 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
175 }
176}
177
178#[cfg(test)]
179mod test {
180 use super::*;
181
182 #[test]
183 fn test_cells() {
184 let lib = LibLibrary::load_file("./data/cells.lib").unwrap();
185 let and2 = lib.cell("AND2").unwrap();
186 let pin = and2.pin("o").unwrap();
187 println!("{:#?}", pin.function);
188 }
189}