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