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}