Skip to main content

liberty_parser/
liberty.rs

1//! Defines a slightly enhanced data structure than the base AST
2//!
3//! Specifically:
4//! * attributes are separated into `simple_attributes` and `complex_attributes`
5//!   struct fields as [IndexMap](std::collections::IndexMap)s.
6//! * `cell` and `pin` groups are brought out into [IndexMap](std::collections::IndexMap)s so they're
7//!   easier to work with
8
9use std::{
10    fmt,
11    ops::{Deref, DerefMut},
12    vec,
13};
14
15use indexmap::IndexMap;
16
17use crate::ast::{GroupItem, LibertyAst, Value};
18
19/// Top-level data structure of a Liberty file
20#[derive(Debug, PartialEq, Clone)]
21pub struct Liberty(pub Vec<Group>);
22
23impl Liberty {
24    pub fn to_ast(self) -> LibertyAst {
25        LibertyAst(self.0.into_iter().map(|g| g.into_group_item()).collect())
26    }
27    pub fn from_ast(ast: LibertyAst) -> Self {
28        Liberty(ast.0.into_iter().map(Group::from_group_item).collect())
29    }
30}
31
32impl Deref for Liberty {
33    type Target = [Group];
34
35    fn deref(&self) -> &Self::Target {
36        self.0.deref()
37    }
38}
39
40impl DerefMut for Liberty {
41    fn deref_mut(&mut self) -> &mut Self::Target {
42        self.0.deref_mut()
43    }
44}
45
46impl From<LibertyAst> for Liberty {
47    fn from(ast: LibertyAst) -> Self {
48        Liberty::from_ast(ast)
49    }
50}
51
52impl fmt::Display for Liberty {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        self.clone().to_ast().fmt(f)
55    }
56}
57
58impl IntoIterator for Liberty {
59    type Item = Group;
60    type IntoIter = ::std::vec::IntoIter<Self::Item>;
61
62    fn into_iter(self) -> Self::IntoIter {
63        self.0.into_iter()
64    }
65}
66
67/// General attribute struct
68///
69/// Attributes can be simple or complex
70#[derive(Debug, PartialEq, Clone)]
71pub enum Attribute {
72    Simple(Value),
73    Complex(Vec<Value>),
74}
75
76/// General group struct
77///
78/// Groups contain simple attributes, complex attributes, and other groups
79#[derive(Debug, PartialEq, Clone)]
80pub struct Group {
81    pub type_: String,
82    pub name: String,
83    pub attributes: IndexMap<String, Vec<Attribute>>,
84    pub subgroups: Vec<Group>,
85}
86
87impl Group {
88    /// Create a group with empty attributes and sub-groups
89    pub fn new(type_: &str, name: &str) -> Self {
90        Self {
91            type_: type_.to_string(),
92            name: name.to_string(),
93            attributes: IndexMap::new(),
94            subgroups: vec![],
95        }
96    }
97
98    /// Convert an AST [GroupItem::Group] variant into a [Group] struct
99    pub fn from_group_item(group_item: GroupItem) -> Self {
100        let (type_, name, items) = group_item.group();
101        let mut attributes: IndexMap<String, Vec<Attribute>> = IndexMap::new();
102        let mut subgroups = vec![];
103        for item in items {
104            match item {
105                GroupItem::SimpleAttr(name, value) => {
106                    if attributes.contains_key(&name) {
107                        attributes
108                            .get_mut(&name)
109                            .unwrap()
110                            .push(Attribute::Simple(value));
111                    } else {
112                        attributes.insert(name, vec![Attribute::Simple(value)]);
113                    }
114                }
115                GroupItem::ComplexAttr(name, value) => {
116                    if attributes.contains_key(&name) {
117                        attributes
118                            .get_mut(&name)
119                            .unwrap()
120                            .push(Attribute::Complex(value));
121                    } else {
122                        attributes.insert(name, vec![Attribute::Complex(value)]);
123                    }
124                }
125                GroupItem::Group(type_, name, items) => {
126                    subgroups.push(Group::from_group_item(GroupItem::Group(type_, name, items)));
127                }
128                _ => {}
129            }
130        }
131        Self {
132            name,
133            type_,
134            attributes,
135            subgroups,
136        }
137    }
138
139    /// Convert a [Group] struct into a [GroupItem::Group] variant
140    pub fn into_group_item(self) -> GroupItem {
141        let mut items: Vec<GroupItem> =
142            Vec::with_capacity(self.attributes.len() + self.subgroups.len());
143        items.extend(self.attributes.into_iter().flat_map(|(name, attrs)| {
144            attrs.into_iter().map(move |attr| match attr {
145                Attribute::Simple(value) => GroupItem::SimpleAttr(name.clone(), value),
146                Attribute::Complex(value) => GroupItem::ComplexAttr(name.clone(), value),
147            })
148        }));
149        items.extend(self.subgroups.into_iter().map(|g| g.into_group_item()));
150        GroupItem::Group(self.type_, self.name, items)
151    }
152
153    /// Get first match of complex attribute by name
154    pub fn complex_attribute(&self, name: &str) -> Option<&Vec<Value>> {
155        self.attributes.get(name).and_then(|attrs| {
156            attrs.first().and_then(|attr| match attr {
157                Attribute::Complex(value) => Some(value),
158                _ => None,
159            })
160        })
161    }
162
163    /// Get first match of simple attribute by name
164    pub fn simple_attribute(&self, name: &str) -> Option<&Value> {
165        self.attributes.get(name).and_then(|attrs| {
166            attrs.first().and_then(|attr| match attr {
167                Attribute::Simple(value) => Some(value),
168                _ => None,
169            })
170        })
171    }
172
173    /// Iterate over the complex attributes
174    pub fn iter_complex_attributes(&self) -> impl Iterator<Item = (&String, &Vec<Value>)> {
175        self.attributes.iter().flat_map(|(name, attrs)| {
176            attrs.iter().filter_map(move |attr| match attr {
177                Attribute::Complex(value) => Some((name, value)),
178                _ => None,
179            })
180        })
181    }
182
183    /// Iterate over the complex attributes mutably
184    pub fn iter_complex_attributes_mut(
185        &mut self,
186    ) -> impl Iterator<Item = (&String, &mut Vec<Value>)> {
187        self.attributes.iter_mut().flat_map(|(name, attrs)| {
188            attrs.iter_mut().filter_map(move |attr| match attr {
189                Attribute::Complex(value) => Some((name, value)),
190                _ => None,
191            })
192        })
193    }
194
195    /// Iterate over the simple attributes
196    pub fn iter_simple_attributes(&self) -> impl Iterator<Item = (&String, &Value)> {
197        self.attributes.iter().flat_map(|(name, attrs)| {
198            attrs.iter().filter_map(move |attr| match attr {
199                Attribute::Simple(value) => Some((name, value)),
200                _ => None,
201            })
202        })
203    }
204
205    /// Iterate over the simple attributes mutably
206    pub fn iter_simple_attributes_mut(&mut self) -> impl Iterator<Item = (&String, &mut Value)> {
207        self.attributes.iter_mut().flat_map(|(name, attrs)| {
208            attrs.iter_mut().filter_map(move |attr| match attr {
209                Attribute::Simple(value) => Some((name, value)),
210                _ => None,
211            })
212        })
213    }
214
215    /// Iterate over the subgroups of a given type
216    pub fn iter_subgroups_of_type<'a>(&'a self, type_: &'a str) -> impl Iterator<Item = &'a Group> {
217        self.subgroups.iter().filter(move |g| g.type_ == type_)
218    }
219
220    /// Iterate over the subgroups of a given type mutably
221    pub fn iter_subgroups_of_type_mut<'a>(
222        &'a mut self,
223        type_: &'a str,
224    ) -> impl Iterator<Item = &'a mut Group> {
225        self.subgroups.iter_mut().filter(move |g| g.type_ == type_)
226    }
227
228    /// Iterate over the subgroups
229    pub fn iter_subgroups(&self) -> impl Iterator<Item = &Group> {
230        self.subgroups.iter()
231    }
232
233    /// Iterate over the subgroups mutably
234    pub fn iter_subgroups_mut(&mut self) -> impl Iterator<Item = &mut Group> {
235        self.subgroups.iter_mut()
236    }
237
238    /// Get cell by name
239    pub fn get_cell(&self, name: &str) -> Option<&Group> {
240        self.iter_subgroups_of_type("cell").find(|g| g.name == name)
241    }
242
243    /// Get cell by name mutably
244    pub fn get_cell_mut(&mut self, name: &str) -> Option<&mut Group> {
245        self.iter_subgroups_of_type_mut("cell")
246            .find(|g| g.name == name)
247    }
248
249    /// Get pin by name
250    pub fn get_pin(&self, name: &str) -> Option<&Group> {
251        self.iter_subgroups_of_type("pin").find(|g| g.name == name)
252    }
253
254    /// Get pin by name mutably
255    pub fn get_pin_mut(&mut self, name: &str) -> Option<&mut Group> {
256        self.iter_subgroups_of_type_mut("pin")
257            .find(|g| g.name == name)
258    }
259
260    /// Iterate over the cells
261    pub fn iter_cells(&self) -> impl Iterator<Item = &Group> {
262        self.iter_subgroups_of_type("cell")
263    }
264
265    /// Iterate over the cells mutably
266    pub fn iter_cells_mut(&mut self) -> impl Iterator<Item = &mut Group> {
267        self.iter_subgroups_of_type_mut("cell")
268    }
269
270    /// Iterate over the pins
271    pub fn iter_pins(&self) -> impl Iterator<Item = &Group> {
272        self.iter_subgroups_of_type("pin")
273    }
274
275    /// Iterate over the pins mutably
276    pub fn iter_pins_mut(&mut self) -> impl Iterator<Item = &mut Group> {
277        self.iter_subgroups_of_type_mut("pin")
278    }
279}