reda_lib/model/
mod.rs

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}