1use crate::stream_parser::{LefDefLexer, LefDefParseError};
9use itertools::PeekingNext;
10use libreda_stream_parser::{tokenize, Tokenized};
11use std::fmt;
12use std::str::FromStr;
13
14#[derive(Clone, Debug)]
16pub enum PropertyType {
17 Integer,
19 Real,
21 String,
23}
24
25impl FromStr for PropertyType {
26 type Err = ();
27
28 fn from_str(input: &str) -> Result<Self, Self::Err> {
29 match input {
30 "INTEGER" => Ok(Self::Integer),
31 "REAL" => Ok(Self::Real),
32 "STRING" => Ok(Self::String),
33 _ => Err(()),
34 }
35 }
36}
37
38impl fmt::Display for PropertyType {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self {
41 Self::Integer => f.write_str("INTEGER"),
42 Self::Real => f.write_str("REAL"),
43 Self::String => f.write_str("STRING"),
44 }
45 }
46}
47
48#[derive(Clone, Debug)]
50pub enum PropertyValue {
51 Int(i32),
53 Real(f64),
55 String(String),
57}
58
59impl fmt::Display for PropertyValue {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 PropertyValue::Int(v) => write!(f, "{}", v),
63 PropertyValue::Real(v) => write!(f, "{}", v),
64 PropertyValue::String(v) => write!(f, r#""{}""#, v),
65 }
66 }
67}
68
69pub fn read_point<T: FromStr, I>(
71 tokens: &mut Tokenized<I, LefDefLexer>,
72) -> Result<(T, T), LefDefParseError>
73where
74 I: Iterator<Item = char> + PeekingNext,
75{
76 let uses_parentheses = tokens.test_str("(")?;
78 let x: T = tokens.take_and_parse()?;
79 tokens.test_str(",")?;
80 let y: T = tokens.take_and_parse()?;
81 if uses_parentheses {
82 tokens.expect_str(")")?;
83 }
84
85 Ok((x, y))
86}
87
88pub fn read_polygon<T: FromStr, I>(
90 tokens: &mut Tokenized<I, LefDefLexer>,
91) -> Result<Vec<(T, T)>, LefDefParseError>
92where
93 I: Iterator<Item = char> + PeekingNext,
94{
95 let mut points = Vec::new();
97 loop {
98 if tokens.test_str(";")? {
99 break;
100 } else {
101 points.push(read_point(tokens)?);
102 }
103 }
104
105 Ok(points)
106}
107
108pub fn read_rect<T: FromStr, I>(
110 tokens: &mut Tokenized<I, LefDefLexer>,
111) -> Result<((T, T), (T, T)), LefDefParseError>
112where
113 I: Iterator<Item = char> + PeekingNext,
114{
115 let p1 = read_point(tokens)?;
116 let p2 = read_point(tokens)?;
117
118 Ok((p1, p2))
119}
120
121#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
123pub struct Symmetry {
124 x: bool,
126 y: bool,
128 r90: bool,
130}
131
132impl Symmetry {
133 pub fn new(x: bool, y: bool, r90: bool) -> Self {
135 Self { x, y, r90 }
136 }
137
138 pub fn x() -> Self {
140 Self::new(true, false, false)
141 }
142 pub fn y() -> Self {
144 Self::new(false, true, false)
145 }
146 pub fn r90() -> Self {
148 Self::new(false, false, true)
149 }
150
151 pub fn union(self, other: Self) -> Self {
153 Self {
154 x: self.x | other.x,
155 y: self.y | other.y,
156 r90: self.r90 | other.r90,
157 }
158 }
159}
160
161impl FromStr for Symmetry {
162 type Err = ();
163
164 fn from_str(input: &str) -> Result<Self, Self::Err> {
165 match input {
166 "X" => Ok(Self::x()),
167 "Y" => Ok(Self::y()),
168 "R90" => Ok(Self::r90()),
169 _ => Err(()),
170 }
171 }
172}
173
174impl fmt::Display for Symmetry {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 if self.x {
177 f.write_str("X")?;
178 }
179 if self.y {
180 f.write_str("Y")?;
181 }
182 if self.r90 {
183 f.write_str("R90")?;
184 }
185
186 Ok(())
187 }
188}
189
190#[derive(Clone, Debug, Default)]
192pub struct AntennaRules {
193 model: (),
195 area_ratio: (),
196 diff_area_ration: (),
197 cum_area_ratio: (),
198 cum_diff_area_ratio: (),
199 }
201
202#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
204pub enum Orient {
205 N,
207 S,
209 E,
211 W,
213 FN,
215 FS,
217 FE,
219 FW,
221}
222
223impl Default for Orient {
224 fn default() -> Self {
225 Self::N
226 }
227}
228
229impl Orient {
230 pub fn decomposed(&self) -> (Self, bool) {
236 match self {
237 Orient::FN => (Orient::N, true),
238 Orient::FS => (Orient::S, true),
239 Orient::FE => (Orient::E, true),
240 Orient::FW => (Orient::W, true),
241 other => (*other, false),
242 }
243 }
244
245 pub fn flipped(&self) -> Self {
248 use Orient::*;
249 match self {
250 N => FN,
251 S => FS,
252 E => FE,
253 W => FW,
254 FN => N,
255 FS => S,
256 FE => E,
257 FW => W,
258 }
259 }
260}
261
262impl FromStr for Orient {
263 type Err = ();
264
265 fn from_str(input: &str) -> Result<Self, Self::Err> {
266 match input {
267 "N" => Ok(Self::N),
268 "S" => Ok(Self::S),
269 "E" => Ok(Self::E),
270 "W" => Ok(Self::W),
271 "FN" => Ok(Self::FN),
272 "FS" => Ok(Self::FS),
273 "FE" => Ok(Self::FE),
274 "FW" => Ok(Self::FW),
275 _ => Err(()),
276 }
277 }
278}
279
280impl fmt::Display for Orient {
281 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282 match self {
283 Self::N => f.write_str("N"),
284 Self::S => f.write_str("S"),
285 Self::E => f.write_str("E"),
286 Self::W => f.write_str("W"),
287 Self::FN => f.write_str("FN"),
288 Self::FS => f.write_str("FS"),
289 Self::FE => f.write_str("FE"),
290 Self::FW => f.write_str("FW"),
291 }
292 }
293}
294
295#[derive(Copy, Clone, Debug, PartialEq, Eq)]
297pub enum PinDirection {
298 Input,
300 Output(bool),
302 Inout,
304 Feedthru,
306}
307
308impl FromStr for PinDirection {
309 type Err = ();
310
311 fn from_str(input: &str) -> Result<Self, Self::Err> {
312 match input {
313 "INPUT" => Ok(Self::Input),
314 "OUTPUT" => Ok(Self::Output(false)),
315 "INOUT" => Ok(Self::Inout),
316 "FEEDTHRU" => Ok(Self::Feedthru),
317 _ => Err(()),
318 }
319 }
320}
321
322impl fmt::Display for PinDirection {
323 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
324 match self {
325 Self::Input => f.write_str("INPUT"),
326 Self::Output(false) => f.write_str("OUTPUT"),
327 Self::Output(true) => f.write_str("OUTPUT TRISTATE"),
328 Self::Inout => f.write_str("INOUT"),
329 Self::Feedthru => f.write_str("FEEDTHRU"),
330 }
331 }
332}