reda_lib/model/
mod.rs

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}