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_literal_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.literal().context(ctx)?)),
99            None => Ok(None),
100        }
101    }
102
103    pub fn attr_vector_opt<S, F>(&self, attr_name: &str, ctx: &F) -> Result<Option<&[LibValue]>, LibError>  
104    where 
105        S: Into<String>,
106        F: Fn() -> S
107    {
108        match self.attr(attr_name) {
109            Some(v) => Ok(Some(v.vector().context(ctx)?)),
110            None => Ok(None),
111        }
112    }
113
114    pub fn attr_expr_opt<S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<Option<LibExpr>, LibError> {
115        match self.attr(attr_name) {
116            Some(v) => {
117                let s = v.string().context(ctx)?;
118                let expr = LibExpr::from_str(s).context(ctx)?;
119                Ok(Some(expr))
120            }
121            None => Ok(None),
122        }
123    }
124
125    pub fn attr_floats_arr_opt<const N: usize, S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<Option<[f64; N]>, LibError> {
126        match self.attr(attr_name) {
127            Some(v) => {
128                let vs = v.vector().context(ctx)?;
129                if vs.len() != N {
130                    Err(LibError::Parse(format!("expect float len {}, got {}", N, vs.len())))?;
131                }
132                let mut fs = [0.0; N];
133                for i in 0..N {
134                    let v = &vs[i];
135                    let f = v.float().context(ctx)?;
136                    fs[i] = f;
137                }
138                Ok(Some(fs))
139            }
140            None => Ok(None),
141        }
142    }
143
144    pub fn attr_floats_opt<S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<Option<Vec<f64>>, LibError> {
145        match self.attr(attr_name) {
146            Some(v) => {
147                let vs = v.vector().context(ctx)?;
148                if vs.len() != 1 {
149                    Err(LibError::Parse(format!("expect one string element in {}", attr_name)))?;
150                }
151                let vs = &vs[0];
152                let values = vs.floats().context(ctx)?;
153                Ok(Some(values))
154            }
155            None => Ok(None),
156        }
157    }
158
159    pub fn attr_parse_opt<T, S, F>(&self, attr_name: &str, ctx: &F) -> Result<Option<T>, LibError> 
160    where 
161        T: FromStr,
162        T::Err: Error,
163        S: Into<String>,
164        F: Fn() -> S
165    {
166        match self.attr(attr_name) {
167            Some(v) => {
168                let s = v.ident().context(ctx)?;
169                let v = T::from_str(s).map_err(|e| LibError::Parse(e.to_string())).context(ctx)?;
170                Ok(Some(v))
171            }
172            None => Ok(None),
173        }
174    }
175
176    pub fn attr_parse_string_opt<T, S, F>(&self, attr_name: &str, ctx: &F) -> Result<Option<T>, LibError> 
177    where 
178        T: FromStr,
179        T::Err: Error,
180        S: Into<String>,
181        F: Fn() -> S
182    {
183        match self.attr(attr_name) {
184            Some(v) => {
185                let s = v.string().context(ctx)?;
186                let v = T::from_str(s).map_err(|e| LibError::Parse(e.to_string())).context(ctx)?;
187                Ok(Some(v))
188            }
189            None => Ok(None),
190        }
191    }
192
193    pub fn attr_bool<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<bool, LibError> {
194        let v = self.attr_bool_opt(attr_name, ctx)?;
195        v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
196    }
197
198    pub fn attr_float<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<f64, LibError> {
199        let v = self.attr_float_opt(attr_name, ctx)?;
200        v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
201    }
202
203    pub fn attr_string<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<&str, LibError> {
204        let v = self.attr_string_opt(attr_name, ctx)?;
205        v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
206    }
207
208    pub fn attr_ident<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<&str, LibError> {
209        let v = self.attr_ident_opt(attr_name, ctx)?;
210        v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
211    }
212
213    pub fn attr_lliteral<S: Into<String>>(&self, attr_name: &str, ctx: impl Fn() -> S) -> Result<&str, LibError> {
214        let v = self.attr_ident_opt(attr_name, ctx)?;
215        v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
216    }
217
218    pub fn attr_expr<S: Into<String>>(&self, attr_name: &str, ctx: &impl Fn() -> S) -> Result<LibExpr, LibError> {
219        let v = self.attr_expr_opt(attr_name, ctx)?;
220        v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
221    }
222
223    pub fn attr_parse<T, S, F>(&self, attr_name: &str, ctx: &F) -> Result<T, LibError> 
224    where 
225        T: FromStr,
226        T::Err: Error,
227        S: Into<String>,
228        F: Fn() -> S
229    {
230        let v = self.attr_parse_opt(attr_name, ctx)?;
231        v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
232    }
233
234    pub fn attr_parse_string<T, S, F>(&self, attr_name: &str, ctx: &F) -> Result<T, LibError> 
235    where 
236        T: FromStr,
237        T::Err: Error,
238        S: Into<String>,
239        F: Fn() -> S
240    {
241        let v = self.attr_parse_string_opt(attr_name, ctx)?;
242        v.ok_or_else(|| LibError::MissAttr(attr_name.into()))
243    }
244
245    pub fn attr_vector<S, F>(&self, attr_name: &str, ctx: &F) -> Result<&[LibValue], LibError>  
246    where 
247        S: Into<String>,
248        F: Fn() -> S
249    {
250        let v = self.attr_vector_opt(attr_name, ctx)?;
251        v.ok_or_else(|| LibError::MissAttr(attr_name.into())) 
252    }
253}
254
255#[cfg(test)]
256mod test {
257    use super::*;
258
259    #[test]
260    fn test_cells() {
261        let lib = LibLibrary::load_file("./data/cells.lib").unwrap();
262        let and2 = lib.cell("AND2").unwrap();
263        let pin = and2.pin("o").unwrap();
264        println!("{:#?}", pin.function);
265    }
266}