1use std::collections::HashMap;
10
11use crate::ast::{GroupItem, LibertyAst, Value};
12
13#[derive(Debug, PartialEq, Clone)]
15pub struct Liberty(pub Vec<Library>);
16
17impl Liberty {
18 pub fn to_ast(self) -> LibertyAst {
19 LibertyAst(
20 self.0
21 .into_iter()
22 .map(|g| g.into_group().into_group_item())
23 .collect(),
24 )
25 }
26 pub fn from_ast(ast: LibertyAst) -> Self {
27 Liberty(
28 ast.0
29 .into_iter()
30 .map(|g| Library::from_group(Group::from_group_item(g)))
31 .collect(),
32 )
33 }
34}
35
36impl IntoIterator for Liberty {
37 type Item = Library;
38 type IntoIter = ::std::vec::IntoIter<Self::Item>;
39
40 fn into_iter(self) -> Self::IntoIter {
41 self.0.into_iter()
42 }
43}
44
45#[derive(Debug, PartialEq, Clone)]
50pub struct Library {
51 pub name: String,
52 pub simple_attributes: HashMap<String, Value>,
53 pub complex_attributes: HashMap<String, Vec<Value>>,
54 pub groups: Vec<Group>,
55 pub cells: HashMap<String, Cell>,
56}
57
58impl Library {
59 pub fn new(name: &str) -> Self {
60 Self {
61 name: name.to_string(),
62 simple_attributes: HashMap::new(),
63 complex_attributes: HashMap::new(),
64 groups: vec![],
65 cells: HashMap::new(),
66 }
67 }
68}
69
70#[derive(Debug, PartialEq, Clone)]
74pub struct Group {
75 pub type_: String,
76 pub name: String,
77 pub simple_attributes: HashMap<String, Value>,
78 pub complex_attributes: HashMap<String, Vec<Value>>,
79 pub groups: Vec<Group>,
80}
81
82impl Group {
83 pub fn new(type_: &str, name: &str) -> Self {
85 Self {
86 type_: type_.to_string(),
87 name: name.to_string(),
88 simple_attributes: HashMap::new(),
89 complex_attributes: HashMap::new(),
90 groups: vec![],
91 }
92 }
93
94 pub fn from_group_item(group_item: GroupItem) -> Self {
96 let (type_, name, items) = group_item.group();
97 let mut simple_attributes: HashMap<String, Value> = HashMap::new();
98 let mut complex_attributes: HashMap<String, Vec<Value>> = HashMap::new();
99 let mut groups: Vec<Self> = vec![];
100 for item in items {
101 match item {
102 GroupItem::SimpleAttr(name, value) => {
103 simple_attributes.insert(name, value);
104 }
105 GroupItem::ComplexAttr(name, value) => {
106 complex_attributes.insert(name, value);
107 }
108 GroupItem::Group(type_, name, items) => {
109 groups.push(Group::from_group_item(GroupItem::Group(type_, name, items)));
110 }
111 _ => {}
112 }
113 }
114 Self {
115 name: name,
116 type_: type_,
117 simple_attributes: simple_attributes,
118 complex_attributes: complex_attributes,
119 groups: groups,
120 }
121 }
122
123 pub fn into_group_item(self) -> GroupItem {
125 let mut items: Vec<GroupItem> = Vec::with_capacity(
126 self.simple_attributes.len() + self.complex_attributes.len() + self.groups.len(),
127 );
128 items.extend(
129 self.simple_attributes
130 .into_iter()
131 .map(|(name, value)| GroupItem::SimpleAttr(name, value)),
132 );
133 items.extend(
134 self.complex_attributes
135 .into_iter()
136 .map(|(name, value)| GroupItem::ComplexAttr(name, value)),
137 );
138 items.extend(self.groups.into_iter().map(|g| g.into_group_item()));
139 GroupItem::Group(self.type_, self.name, items)
140 }
141}
142
143#[derive(Debug, PartialEq, Clone)]
145pub struct Cell {
146 pub name: String,
147 pub simple_attributes: HashMap<String, Value>,
148 pub complex_attributes: HashMap<String, Vec<Value>>,
149 pub groups: Vec<Group>,
150 pub pins: HashMap<String, Pin>,
151}
152
153impl Cell {
154 pub fn new(name: &str) -> Self {
156 Self {
157 name: name.to_string(),
158 simple_attributes: HashMap::new(),
159 complex_attributes: HashMap::new(),
160 groups: vec![],
161 pins: HashMap::new(),
162 }
163 }
164}
165
166#[derive(Debug, PartialEq, Clone)]
168pub struct Pin {
169 pub name: String,
170 pub simple_attributes: HashMap<String, Value>,
171 pub complex_attributes: HashMap<String, Vec<Value>>,
172 pub groups: Vec<Group>,
173}
174
175impl Pin {
176 pub fn new(name: &str) -> Self {
178 Self {
179 name: name.to_string(),
180 simple_attributes: HashMap::new(),
181 complex_attributes: HashMap::new(),
182 groups: vec![],
183 }
184 }
185}
186
187pub trait FromGroup {
191 type Item;
192
193 fn from_group(group: Group) -> Self::Item;
194}
195
196pub trait ToGroup {
197 type Item;
198
199 fn into_group(self) -> Group;
200}
201
202impl FromGroup for Library {
203 type Item = Library;
204 fn from_group(group: Group) -> Self::Item {
205 let (cells, groups) = group.groups.into_iter().partition(|g| g.type_ == "cell");
206 Self {
207 name: group.name,
208 simple_attributes: group.simple_attributes,
209 complex_attributes: group.complex_attributes,
210 groups: groups,
211 cells: cells.into_iter().fold(HashMap::new(), |mut acc, cell| {
212 acc.insert(cell.name.clone(), Cell::from_group(cell));
213 acc
214 }),
215 }
216 }
217}
218
219impl ToGroup for Library {
220 type Item = Library;
221 fn into_group(self) -> Group {
222 let mut groups: Vec<Group> = Vec::with_capacity(self.groups.len() + self.cells.len());
223 groups.extend(self.cells.into_iter().map(|(_, cell)| cell.into_group()));
224 groups.extend(self.groups);
225 Group {
226 name: self.name,
227 type_: String::from("library"),
228 simple_attributes: self.simple_attributes,
229 complex_attributes: self.complex_attributes,
230 groups: groups,
231 }
232 }
233}
234
235impl FromGroup for Cell {
236 type Item = Cell;
237 fn from_group(group: Group) -> Self::Item {
238 let (pins, groups) = group.groups.into_iter().partition(|g| g.type_ == "pin");
239 Self {
240 name: group.name,
241 simple_attributes: group.simple_attributes,
242 complex_attributes: group.complex_attributes,
243 groups: groups,
244 pins: pins.into_iter().fold(HashMap::new(), |mut acc, pin| {
245 acc.insert(pin.name.clone(), Pin::from_group(pin));
246 acc
247 }),
248 }
249 }
250}
251
252impl ToGroup for Cell {
253 type Item = Cell;
254
255 fn into_group(self) -> Group {
256 let mut groups: Vec<Group> = Vec::with_capacity(self.groups.len() + self.pins.len());
257 groups.extend(self.pins.into_iter().map(|(_, pin)| pin.into_group()));
258 groups.extend(self.groups);
259 Group {
260 name: self.name,
261 type_: String::from("cell"),
262 simple_attributes: self.simple_attributes,
263 complex_attributes: self.complex_attributes,
264 groups: groups,
265 }
266 }
267}
268
269impl FromGroup for Pin {
270 type Item = Pin;
271 fn from_group(group: Group) -> Self::Item {
272 Self {
273 name: group.name,
274 simple_attributes: group.simple_attributes,
275 complex_attributes: group.complex_attributes,
276 groups: group.groups,
277 }
278 }
279}
280
281impl ToGroup for Pin {
282 type Item = Pin;
283 fn into_group(self) -> Group {
284 Group {
285 name: self.name,
286 type_: String::from("pin"),
287 simple_attributes: self.simple_attributes,
288 complex_attributes: self.complex_attributes,
289 groups: self.groups,
290 }
291 }
292}
293
294#[cfg(test)]
295mod test {
296 use super::*;
297
298 #[test]
299 fn test_iter() {
300 let lib = Liberty(vec![Library::new("mylib")]);
301 let mut iter = lib.into_iter();
302 assert_eq!(iter.next(), Some(Library::new("mylib")));
303 assert_eq!(iter.next(), None);
304 }
305
306 #[test]
307 fn test_pin_into_group() {
308 let mut pin = Pin::new("my_pin");
309 pin.groups.push(Group::new("gtype", "gname"));
310 let group = pin.into_group();
311 assert_eq!(group.type_, "pin");
312 assert_eq!(group.name, "my_pin");
313 assert_eq!(group.groups.len(), 1);
314 }
315
316 #[test]
317 fn test_pin_from_group() {
318 let mut group = Group::new("pin", "a");
319 group.groups.push(Group::new("gtype", "gname"));
320 let pin = Pin::from_group(group);
321 assert_eq!(pin.name, "a");
322 assert_eq!(pin.groups.len(), 1);
323 }
324
325 #[test]
326 fn test_cell_into_group() {
327 let mut cell = Cell::new("my_cell");
328 cell.groups.push(Group::new("gtype", "gname"));
329 cell.pins.insert("a".to_string(), Pin::new("a"));
330 cell.pins.insert("b".to_string(), Pin::new("b"));
331 let group = cell.into_group();
332 assert_eq!(group.type_, "cell");
333 assert_eq!(group.name, "my_cell");
334 assert_eq!(group.groups.len(), 3);
335 }
336
337 #[test]
338 fn test_cell_from_group() {
339 let mut group = Group::new("cell", "AND2");
340 group.groups.push(Group::new("gtype", "gname"));
341 group.groups.push(Group::new("pin", "a"));
342 group.groups.push(Group::new("pin", "b"));
343 let cell = Cell::from_group(group);
344 assert_eq!(cell.name, "AND2");
345 assert_eq!(cell.groups.len(), 1);
346 assert_eq!(cell.pins.len(), 2);
347 }
348
349 #[test]
350 fn test_library_into_group() {
351 let mut lib = Library::new("my_lib");
352 lib.groups.push(Group::new("gtype", "gname"));
353 lib.cells.insert("AND2".to_string(), Cell::new("AND2"));
354 lib.cells.insert("NAND2".to_string(), Cell::new("NAND2"));
355 let group = lib.into_group();
356 assert_eq!(group.type_, "library");
357 assert_eq!(group.name, "my_lib");
358 assert_eq!(group.groups.len(), 3);
359 }
360
361 #[test]
362 fn test_lib_from_group() {
363 let mut group = Group::new("library", "mylib");
364 group.groups.push(Group::new("gtype", "gname"));
365 let mut cell = Group::new("cell", "AND2");
366 cell.groups.push(Group::new("pin", "a"));
367 cell.groups.push(Group::new("pin", "b"));
368 group.groups.push(cell);
369 let lib = Library::from_group(group);
370 assert_eq!(lib.name, "mylib");
371 assert_eq!(lib.groups.len(), 1);
372 assert_eq!(lib.cells.len(), 1);
373 let converted_cell = lib.cells.get("AND2").unwrap();
374 assert_eq!(converted_cell.name, "AND2");
375 assert_eq!(converted_cell.groups.len(), 0);
376 assert_eq!(converted_cell.pins.len(), 2);
377 }
378}