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_iteral_opt<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<Option<&str>, LibError> {
95 match self.attr(attr_name) {
96 Some(v) => Ok(Some(v.iteral().context(ctx)?)),
97 None => Ok(None),
98 }
99 }
100
101 pub fn attr_expr_opt<S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<Option<LibExpr>, LibError> {
102 match self.attr(attr_name) {
103 Some(v) => {
104 let s = v.string().context(ctx)?;
105 let expr = LibExpr::from_str(s).context(ctx)?;
106 Ok(Some(expr))
107 }
108 None => Ok(None),
109 }
110 }
111
112 pub fn attr_floats_opt<const N: usize, S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<Option<[f64; N]>, LibError> {
113 match self.attr(attr_name) {
114 Some(v) => {
115 let vs = v.vector().context(ctx)?;
116 if vs.len() != N {
117 Err(LibError::Parse(format!("expect float len {}, got {}", N, vs.len())))?;
118 }
119 let mut fs = [0.0; N];
120 for i in 0..N {
121 let v = &vs[i];
122 let f = v.float().context(ctx)?;
123 fs[i] = f;
124 }
125 Ok(Some(fs))
126 }
127 None => Ok(None),
128 }
129 }
130
131 pub fn attr_parse_opt<T, S, F>(&self, attr_name: &str, ctx: &F) -> Result<Option<T>, LibError>
132 where
133 T: FromStr,
134 T::Err: Error,
135 S: Into<String>,
136 F: Fn() -> S
137 {
138 match self.attr(attr_name) {
139 Some(v) => {
140 let s = v.ident().context(ctx)?;
141 let v = T::from_str(s).map_err(|e| LibError::Parse(e.to_string())).context(ctx)?;
142 Ok(Some(v))
143 }
144 None => Ok(None),
145 }
146 }
147
148 pub fn attr_bool<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<bool, LibError> {
149 let v = self.attr_bool_opt(attr_name, ctx)?;
150 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
151 }
152
153 pub fn attr_float<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<f64, LibError> {
154 let v = self.attr_float_opt(attr_name, ctx)?;
155 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
156 }
157
158 pub fn attr_string<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<&str, LibError> {
159 let v = self.attr_string_opt(attr_name, ctx)?;
160 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
161 }
162
163 pub fn attr_ident<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<&str, LibError> {
164 let v = self.attr_ident_opt(attr_name, ctx)?;
165 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
166 }
167
168 pub fn attr_literal<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<&str, LibError> {
169 let v = self.attr_ident_opt(attr_name, ctx)?;
170 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
171 }
172
173 pub fn attr_expr<S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<LibExpr, LibError> {
174 let v = self.attr_expr_opt(attr_name, ctx)?;
175 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
176 }
177
178 pub fn attr_parse<T, S, F>(&self, attr_name: &str, ctx: &F) -> Result<T, LibError>
179 where
180 T: FromStr,
181 T::Err: Error,
182 S: Into<String>,
183 F: Fn() -> S
184 {
185 let v = self.attr_parse_opt(attr_name, ctx)?;
186 v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
187 }
188}
189
190#[cfg(test)]
191mod test {
192 use super::*;
193
194 #[test]
195 fn test_cells() {
196 let lib = LibLibrary::load_file("./data/cells.lib").unwrap();
197 let and2 = lib.cell("AND2").unwrap();
198 let pin = and2.pin("o").unwrap();
199 println!("{:#?}", pin.function);
200 }
201}