sdc_parser/
object.rs

1use crate::util::*;
2use combine::error::{ParseError, ParseResult};
3use combine::parser::Parser;
4use combine::{attempt, choice, many, many1, parser, Stream};
5use std::fmt;
6
7// -----------------------------------------------------------------------------
8
9/// Object
10#[derive(Clone, Debug, PartialEq)]
11pub enum Object {
12    AllClocks(AllClocks),
13    AllInputs(AllInputs),
14    AllOutputs(AllOutputs),
15    AllRegisters(AllRegisters),
16    CurrentDesign(CurrentDesign),
17    GetCells(GetCells),
18    GetClocks(GetClocks),
19    GetLibCells(GetLibCells),
20    GetLibPins(GetLibPins),
21    GetLibs(GetLibs),
22    GetNets(GetNets),
23    GetPins(GetPins),
24    GetPorts(GetPorts),
25    List(List),
26    String(ObjectString),
27    Unknown,
28}
29
30impl Default for Object {
31    fn default() -> Self {
32        Object::Unknown
33    }
34}
35
36impl fmt::Display for Object {
37    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38        match self {
39            Object::AllClocks(x) => write!(f, "{}", x),
40            Object::AllInputs(x) => write!(f, "{}", x),
41            Object::AllOutputs(x) => write!(f, "{}", x),
42            Object::AllRegisters(x) => write!(f, "{}", x),
43            Object::CurrentDesign(x) => write!(f, "{}", x),
44            Object::GetCells(x) => write!(f, "{}", x),
45            Object::GetClocks(x) => write!(f, "{}", x),
46            Object::GetLibCells(x) => write!(f, "{}", x),
47            Object::GetLibPins(x) => write!(f, "{}", x),
48            Object::GetLibs(x) => write!(f, "{}", x),
49            Object::GetNets(x) => write!(f, "{}", x),
50            Object::GetPins(x) => write!(f, "{}", x),
51            Object::GetPorts(x) => write!(f, "{}", x),
52            Object::List(x) => write!(f, "{}", x),
53            Object::String(x) => write!(f, "{}", x),
54            Object::Unknown => write!(f, ""),
55        }
56    }
57}
58
59pub(crate) fn object<I>(input: &mut I) -> ParseResult<Object, I>
60where
61    I: Stream<Item = char>,
62    I::Error: ParseError<I::Item, I::Range, I::Position>,
63{
64    let items = (
65        attempt(all_clocks()),
66        attempt(all_inputs()),
67        attempt(all_outputs()),
68        attempt(all_registers()),
69        attempt(current_design()),
70        attempt(get_cells()),
71        attempt(get_clocks()),
72        attempt(get_lib_cells()),
73        attempt(get_lib_pins()),
74        attempt(get_libs()),
75        attempt(get_nets()),
76        attempt(get_pins()),
77        attempt(get_ports()),
78        attempt(list()),
79        attempt(string()),
80    );
81    choice(items).parse_stream(input)
82}
83
84// -----------------------------------------------------------------------------
85
86enum ObjectArg {
87    AsyncPins,
88    Cells,
89    Clock(String),
90    ClockPins,
91    DataPins,
92    EdgeTriggered,
93    FallClock(String),
94    Hierarchical,
95    Hsc(String),
96    LevelSensitive,
97    MasterSlave,
98    NoHierarchy,
99    Nocase,
100    OfObject(Object),
101    OutputPins,
102    Patterns(Vec<String>),
103    Regexp,
104    RiseClock(String),
105    SlaveClockPins,
106}
107
108// -----------------------------------------------------------------------------
109
110/// A type containing information of `all_clocks`
111#[derive(Clone, Debug, Default, PartialEq)]
112pub struct AllClocks;
113
114impl fmt::Display for AllClocks {
115    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116        write!(f, "[all_clocks]")
117    }
118}
119
120fn all_clocks<I>() -> impl Parser<Input = I, Output = Object>
121where
122    I: Stream<Item = char>,
123    I::Error: ParseError<I::Item, I::Range, I::Position>,
124{
125    let command = symbol("all_clocks").map(|_| Object::AllClocks(AllClocks {}));
126    brackets(command)
127}
128
129#[test]
130fn test_all_clocks() {
131    let mut parser = parser(object);
132    let tgt = "[all_clocks]";
133    let ret = parser.parse(tgt).unwrap().0;
134    assert_eq!(Object::AllClocks(AllClocks {}), ret);
135    assert_eq!(tgt, format!("{}", ret));
136}
137
138// -----------------------------------------------------------------------------
139
140/// A type containing information of `all_inputs`
141#[derive(Clone, Debug, Default, PartialEq)]
142pub struct AllInputs {
143    pub level_sensitive: bool,
144    pub edge_triggered: bool,
145    pub clock: Option<String>,
146}
147
148impl fmt::Display for AllInputs {
149    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150        let mut args = String::from("");
151        if self.level_sensitive {
152            args.push_str(" -level_sensitive");
153        }
154        if self.edge_triggered {
155            args.push_str(" -edge_triggered");
156        }
157        if let Some(clock) = &self.clock {
158            args.push_str(&format!(" -clock {}", clock));
159        }
160        write!(f, "[all_inputs{}]", args)
161    }
162}
163
164fn all_inputs<I>() -> impl Parser<Input = I, Output = Object>
165where
166    I: Stream<Item = char>,
167    I::Error: ParseError<I::Item, I::Range, I::Position>,
168{
169    let command = symbol("all_inputs");
170    let level_sensitive = symbol("-level_sensitive").map(|_| ObjectArg::LevelSensitive);
171    let edge_triggered = symbol("-edge_triggered").map(|_| ObjectArg::EdgeTriggered);
172    let clock = symbol("-clock").with(item()).map(|x| ObjectArg::Clock(x));
173    let args = (
174        attempt(level_sensitive),
175        attempt(edge_triggered),
176        attempt(clock),
177    );
178    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
179        let mut level_sensitive = false;
180        let mut edge_triggered = false;
181        let mut clock = None;
182        for x in xs {
183            match x {
184                ObjectArg::LevelSensitive => level_sensitive = true,
185                ObjectArg::EdgeTriggered => edge_triggered = true,
186                ObjectArg::Clock(x) => clock = Some(x),
187                _ => unreachable!(),
188            }
189        }
190        Object::AllInputs(AllInputs {
191            level_sensitive,
192            edge_triggered,
193            clock,
194        })
195    })
196}
197
198#[test]
199fn test_all_inputs() {
200    let mut parser = parser(object);
201    let tgt = "[all_inputs -level_sensitive -edge_triggered -clock a]";
202    let ret = parser.parse(tgt).unwrap().0;
203    assert_eq!(
204        Object::AllInputs(AllInputs {
205            level_sensitive: true,
206            edge_triggered: true,
207            clock: Some(String::from("a")),
208        }),
209        ret
210    );
211    assert_eq!(tgt, format!("{}", ret));
212}
213
214// -----------------------------------------------------------------------------
215
216/// A type containing information of `all_outputs`
217#[derive(Clone, Debug, Default, PartialEq)]
218pub struct AllOutputs {
219    pub level_sensitive: bool,
220    pub edge_triggered: bool,
221    pub clock: Option<String>,
222}
223
224impl fmt::Display for AllOutputs {
225    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226        let mut args = String::from("");
227        if self.level_sensitive {
228            args.push_str(" -level_sensitive");
229        }
230        if self.edge_triggered {
231            args.push_str(" -edge_triggered");
232        }
233        if let Some(clock) = &self.clock {
234            args.push_str(&format!(" -clock {}", clock));
235        }
236        write!(f, "[all_outputs{}]", args)
237    }
238}
239
240fn all_outputs<I>() -> impl Parser<Input = I, Output = Object>
241where
242    I: Stream<Item = char>,
243    I::Error: ParseError<I::Item, I::Range, I::Position>,
244{
245    let command = symbol("all_outputs");
246    let level_sensitive = symbol("-level_sensitive").map(|_| ObjectArg::LevelSensitive);
247    let edge_triggered = symbol("-edge_triggered").map(|_| ObjectArg::EdgeTriggered);
248    let clock = symbol("-clock").with(item()).map(|x| ObjectArg::Clock(x));
249    let args = (
250        attempt(level_sensitive),
251        attempt(edge_triggered),
252        attempt(clock),
253    );
254    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
255        let mut level_sensitive = false;
256        let mut edge_triggered = false;
257        let mut clock = None;
258        for x in xs {
259            match x {
260                ObjectArg::LevelSensitive => level_sensitive = true,
261                ObjectArg::EdgeTriggered => edge_triggered = true,
262                ObjectArg::Clock(x) => clock = Some(x),
263                _ => unreachable!(),
264            }
265        }
266        Object::AllOutputs(AllOutputs {
267            level_sensitive,
268            edge_triggered,
269            clock,
270        })
271    })
272}
273
274#[test]
275fn test_all_outputs() {
276    let mut parser = parser(object);
277    let tgt = "[all_outputs -level_sensitive -edge_triggered -clock a]";
278    let ret = parser.parse(tgt).unwrap().0;
279    assert_eq!(
280        Object::AllOutputs(AllOutputs {
281            level_sensitive: true,
282            edge_triggered: true,
283            clock: Some(String::from("a")),
284        }),
285        ret
286    );
287    assert_eq!(tgt, format!("{}", ret));
288}
289
290// -----------------------------------------------------------------------------
291
292/// A type containing information of `all_registers`
293#[derive(Clone, Debug, Default, PartialEq)]
294pub struct AllRegisters {
295    pub no_hierarchy: bool,
296    pub hsc: Option<String>,
297    pub clock: Option<String>,
298    pub rise_clock: Option<String>,
299    pub fall_clock: Option<String>,
300    pub cells: bool,
301    pub data_pins: bool,
302    pub clock_pins: bool,
303    pub slave_clock_pins: bool,
304    pub async_pins: bool,
305    pub output_pins: bool,
306    pub level_sensitive: bool,
307    pub edge_triggered: bool,
308    pub master_slave: bool,
309}
310
311impl fmt::Display for AllRegisters {
312    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
313        let mut args = String::from("");
314        if self.no_hierarchy {
315            args.push_str(" -no_hierarchy");
316        }
317        if let Some(hsc) = &self.hsc {
318            args.push_str(&format!(" -hsc {}", hsc));
319        }
320        if let Some(clock) = &self.clock {
321            args.push_str(&format!(" -clock {}", clock));
322        }
323        if let Some(rise_clock) = &self.rise_clock {
324            args.push_str(&format!(" -rise_clock {}", rise_clock));
325        }
326        if let Some(fall_clock) = &self.fall_clock {
327            args.push_str(&format!(" -fall_clock {}", fall_clock));
328        }
329        if self.cells {
330            args.push_str(" -cells");
331        }
332        if self.data_pins {
333            args.push_str(" -data_pins");
334        }
335        if self.clock_pins {
336            args.push_str(" -clock_pins");
337        }
338        if self.slave_clock_pins {
339            args.push_str(" -slave_clock_pins");
340        }
341        if self.async_pins {
342            args.push_str(" -async_pins");
343        }
344        if self.output_pins {
345            args.push_str(" -output_pins");
346        }
347        if self.level_sensitive {
348            args.push_str(" -level_sensitive");
349        }
350        if self.edge_triggered {
351            args.push_str(" -edge_triggered");
352        }
353        if self.master_slave {
354            args.push_str(" -master_slave");
355        }
356        write!(f, "[all_registers{}]", args)
357    }
358}
359
360fn all_registers<I>() -> impl Parser<Input = I, Output = Object>
361where
362    I: Stream<Item = char>,
363    I::Error: ParseError<I::Item, I::Range, I::Position>,
364{
365    let command = symbol("all_registers");
366    let no_hierarchy = symbol("-no_hierarchy").map(|_| ObjectArg::NoHierarchy);
367    let hsc = symbol("-hsc").with(item()).map(|x| ObjectArg::Hsc(x));
368    let clock = symbol("-clock").with(item()).map(|x| ObjectArg::Clock(x));
369    let rise_clock = symbol("-rise_clock")
370        .with(item())
371        .map(|x| ObjectArg::RiseClock(x));
372    let fall_clock = symbol("-fall_clock")
373        .with(item())
374        .map(|x| ObjectArg::FallClock(x));
375    let cells = symbol("-cells").map(|_| ObjectArg::Cells);
376    let data_pins = symbol("-data_pins").map(|_| ObjectArg::DataPins);
377    let clock_pins = symbol("-clock_pins").map(|_| ObjectArg::ClockPins);
378    let slave_clock_pins = symbol("-slave_clock_pins").map(|_| ObjectArg::SlaveClockPins);
379    let async_pins = symbol("-async_pins").map(|_| ObjectArg::AsyncPins);
380    let output_pins = symbol("-output_pins").map(|_| ObjectArg::OutputPins);
381    let level_sensitive = symbol("-level_sensitive").map(|_| ObjectArg::LevelSensitive);
382    let edge_triggered = symbol("-edge_triggered").map(|_| ObjectArg::EdgeTriggered);
383    let master_slave = symbol("-master_slave").map(|_| ObjectArg::MasterSlave);
384    let args = (
385        attempt(no_hierarchy),
386        attempt(hsc),
387        attempt(clock),
388        attempt(rise_clock),
389        attempt(fall_clock),
390        attempt(cells),
391        attempt(data_pins),
392        attempt(clock_pins),
393        attempt(slave_clock_pins),
394        attempt(async_pins),
395        attempt(output_pins),
396        attempt(level_sensitive),
397        attempt(edge_triggered),
398        attempt(master_slave),
399    );
400    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
401        let mut no_hierarchy = false;
402        let mut hsc = None;
403        let mut clock = None;
404        let mut rise_clock = None;
405        let mut fall_clock = None;
406        let mut cells = false;
407        let mut data_pins = false;
408        let mut clock_pins = false;
409        let mut slave_clock_pins = false;
410        let mut async_pins = false;
411        let mut output_pins = false;
412        let mut level_sensitive = false;
413        let mut edge_triggered = false;
414        let mut master_slave = false;
415        for x in xs {
416            match x {
417                ObjectArg::NoHierarchy => no_hierarchy = true,
418                ObjectArg::Hsc(x) => hsc = Some(x),
419                ObjectArg::Clock(x) => clock = Some(x),
420                ObjectArg::RiseClock(x) => rise_clock = Some(x),
421                ObjectArg::FallClock(x) => fall_clock = Some(x),
422                ObjectArg::Cells => cells = true,
423                ObjectArg::DataPins => data_pins = true,
424                ObjectArg::ClockPins => clock_pins = true,
425                ObjectArg::SlaveClockPins => slave_clock_pins = true,
426                ObjectArg::AsyncPins => async_pins = true,
427                ObjectArg::OutputPins => output_pins = true,
428                ObjectArg::LevelSensitive => level_sensitive = true,
429                ObjectArg::EdgeTriggered => edge_triggered = true,
430                ObjectArg::MasterSlave => master_slave = true,
431                _ => unreachable!(),
432            }
433        }
434        Object::AllRegisters(AllRegisters {
435            no_hierarchy,
436            hsc,
437            clock,
438            rise_clock,
439            fall_clock,
440            cells,
441            data_pins,
442            clock_pins,
443            slave_clock_pins,
444            async_pins,
445            output_pins,
446            level_sensitive,
447            edge_triggered,
448            master_slave,
449        })
450    })
451}
452
453#[test]
454fn test_all_registers() {
455    let mut parser = parser(object);
456    let tgt = "[all_registers -no_hierarchy -hsc a -clock a -rise_clock a -fall_clock a -cells -data_pins -clock_pins -slave_clock_pins -async_pins -output_pins -level_sensitive -edge_triggered -master_slave]";
457    let ret = parser.parse(tgt).unwrap().0;
458    assert_eq!(
459        Object::AllRegisters(AllRegisters {
460            no_hierarchy: true,
461            hsc: Some(String::from("a")),
462            clock: Some(String::from("a")),
463            rise_clock: Some(String::from("a")),
464            fall_clock: Some(String::from("a")),
465            cells: true,
466            data_pins: true,
467            clock_pins: true,
468            slave_clock_pins: true,
469            async_pins: true,
470            output_pins: true,
471            level_sensitive: true,
472            edge_triggered: true,
473            master_slave: true,
474        }),
475        ret
476    );
477    assert_eq!(tgt, format!("{}", ret));
478}
479
480// -----------------------------------------------------------------------------
481
482/// A type containing information of `current_design`
483#[derive(Clone, Debug, Default, PartialEq)]
484pub struct CurrentDesign;
485
486impl fmt::Display for CurrentDesign {
487    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
488        write!(f, "[current_design]")
489    }
490}
491
492fn current_design<I>() -> impl Parser<Input = I, Output = Object>
493where
494    I: Stream<Item = char>,
495    I::Error: ParseError<I::Item, I::Range, I::Position>,
496{
497    let command = symbol("current_design").map(|_| Object::CurrentDesign(CurrentDesign {}));
498    brackets(command)
499}
500
501#[test]
502fn test_current_design() {
503    let mut parser = parser(object);
504    let tgt = "[current_design]";
505    let ret = parser.parse(tgt).unwrap().0;
506    assert_eq!(Object::CurrentDesign(CurrentDesign {}), ret);
507    assert_eq!(tgt, format!("{}", ret));
508}
509
510// -----------------------------------------------------------------------------
511
512/// A type containing information of `get_cells`
513#[derive(Clone, Debug, Default, PartialEq)]
514pub struct GetCells {
515    pub hierarchical: bool,
516    pub hsc: Option<String>,
517    pub regexp: bool,
518    pub nocase: bool,
519    pub of_objects: Option<Box<Object>>,
520    pub patterns: Vec<String>,
521}
522
523impl fmt::Display for GetCells {
524    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
525        let mut args = String::from("");
526        if self.hierarchical {
527            args.push_str(" -hierarchical");
528        }
529        if let Some(hsc) = &self.hsc {
530            args.push_str(&format!(" -hsc {}", hsc));
531        }
532        if self.regexp {
533            args.push_str(" -regexp");
534        }
535        if self.nocase {
536            args.push_str(" -nocase");
537        }
538        if let Some(of_objects) = &self.of_objects {
539            args.push_str(&format!(" -of_objects {}", of_objects));
540        }
541        if self.patterns.len() == 1 {
542            args.push_str(&format!(" {}", self.patterns[0]));
543        } else if self.patterns.len() > 1 {
544            args.push_str(" {");
545            for (i, s) in self.patterns.iter().enumerate() {
546                if i == 0 {
547                    args.push_str(&format!("{}", s));
548                } else {
549                    args.push_str(&format!(" {}", s));
550                }
551            }
552            args.push_str("}");
553        }
554        write!(f, "[get_cells{}]", args)
555    }
556}
557
558fn get_cells<I>() -> impl Parser<Input = I, Output = Object>
559where
560    I: Stream<Item = char>,
561    I::Error: ParseError<I::Item, I::Range, I::Position>,
562{
563    let command = attempt(symbol("get_cells")).or(symbol("get_cell"));
564    let hierarchical = symbol("-hierarchical").map(|_| ObjectArg::Hierarchical);
565    let hsc = symbol("-hsc").with(item()).map(|x| ObjectArg::Hsc(x));
566    let regexp = symbol("-regexp").map(|_| ObjectArg::Regexp);
567    let nocase = symbol("-nocase").map(|_| ObjectArg::Nocase);
568    let of_objects = attempt(symbol("-of_objects"))
569        .or(symbol("-of_object"))
570        .with(parser(object))
571        .map(|x| ObjectArg::OfObject(x));
572    let patterns = choice((braces(parser(braces_strings)), item().map(|x| vec![x])))
573        .map(|x| ObjectArg::Patterns(x));
574    let args = (
575        attempt(hierarchical),
576        attempt(hsc),
577        attempt(regexp),
578        attempt(nocase),
579        attempt(of_objects),
580        patterns,
581    );
582    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
583        let mut hierarchical = false;
584        let mut hsc = None;
585        let mut regexp = false;
586        let mut nocase = false;
587        let mut of_objects = None;
588        let mut patterns = vec![];
589        for x in xs {
590            match x {
591                ObjectArg::Hierarchical => hierarchical = true,
592                ObjectArg::Hsc(x) => hsc = Some(x),
593                ObjectArg::Regexp => regexp = true,
594                ObjectArg::Nocase => nocase = true,
595                ObjectArg::OfObject(x) => of_objects = Some(Box::new(x)),
596                ObjectArg::Patterns(x) => patterns = x,
597                _ => unreachable!(),
598            }
599        }
600        Object::GetCells(GetCells {
601            hierarchical,
602            hsc,
603            regexp,
604            nocase,
605            of_objects,
606            patterns,
607        })
608    })
609}
610
611#[test]
612fn test_get_cells() {
613    let mut parser = parser(object);
614    let tgt = "[get_cells -hierarchical -hsc a -regexp -nocase -of_objects a a]";
615    let ret = parser.parse(tgt).unwrap().0;
616    assert_eq!(
617        Object::GetCells(GetCells {
618            hierarchical: true,
619            hsc: Some(String::from("a")),
620            regexp: true,
621            nocase: true,
622            of_objects: Some(Box::new(Object::String(ObjectString {
623                strings: vec![String::from("a")]
624            }))),
625            patterns: vec![String::from("a")]
626        }),
627        ret
628    );
629    assert_eq!(tgt, format!("{}", ret));
630
631    let tgt = "[get_cells -hierarchical -hsc a -regexp -nocase -of_objects a {a a}]";
632    let ret = parser.parse(tgt).unwrap().0;
633    assert_eq!(
634        Object::GetCells(GetCells {
635            hierarchical: true,
636            hsc: Some(String::from("a")),
637            regexp: true,
638            nocase: true,
639            of_objects: Some(Box::new(Object::String(ObjectString {
640                strings: vec![String::from("a")]
641            }))),
642            patterns: vec![String::from("a"), String::from("a")]
643        }),
644        ret
645    );
646    assert_eq!(tgt, format!("{}", ret));
647}
648
649// -----------------------------------------------------------------------------
650
651/// A type containing information of `get_clocks`
652#[derive(Clone, Debug, Default, PartialEq)]
653pub struct GetClocks {
654    pub regexp: bool,
655    pub nocase: bool,
656    pub patterns: Vec<String>,
657}
658
659impl fmt::Display for GetClocks {
660    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
661        let mut args = String::from("");
662        if self.regexp {
663            args.push_str(" -regexp");
664        }
665        if self.nocase {
666            args.push_str(" -nocase");
667        }
668        if self.patterns.len() == 1 {
669            args.push_str(&format!(" {}", self.patterns[0]));
670        } else if self.patterns.len() > 1 {
671            args.push_str(" {");
672            for (i, s) in self.patterns.iter().enumerate() {
673                if i == 0 {
674                    args.push_str(&format!("{}", s));
675                } else {
676                    args.push_str(&format!(" {}", s));
677                }
678            }
679            args.push_str("}");
680        }
681        write!(f, "[get_clocks{}]", args)
682    }
683}
684
685fn get_clocks<I>() -> impl Parser<Input = I, Output = Object>
686where
687    I: Stream<Item = char>,
688    I::Error: ParseError<I::Item, I::Range, I::Position>,
689{
690    let command = attempt(symbol("get_clocks")).or(symbol("get_clock"));
691    let regexp = symbol("-regexp").map(|_| ObjectArg::Regexp);
692    let nocase = symbol("-nocase").map(|_| ObjectArg::Nocase);
693    let patterns = choice((braces(parser(braces_strings)), item().map(|x| vec![x])))
694        .map(|x| ObjectArg::Patterns(x));
695    let args = (attempt(regexp), attempt(nocase), patterns);
696    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
697        let mut regexp = false;
698        let mut nocase = false;
699        let mut patterns = vec![];
700        for x in xs {
701            match x {
702                ObjectArg::Regexp => regexp = true,
703                ObjectArg::Nocase => nocase = true,
704                ObjectArg::Patterns(x) => patterns = x,
705                _ => unreachable!(),
706            }
707        }
708        Object::GetClocks(GetClocks {
709            regexp,
710            nocase,
711            patterns,
712        })
713    })
714}
715
716#[test]
717fn test_get_clocks() {
718    let mut parser = parser(object);
719    let tgt = "[get_clocks -regexp -nocase a]";
720    let ret = parser.parse(tgt).unwrap().0;
721    assert_eq!(
722        Object::GetClocks(GetClocks {
723            regexp: true,
724            nocase: true,
725            patterns: vec![String::from("a")]
726        }),
727        ret
728    );
729    assert_eq!(tgt, format!("{}", ret));
730
731    let tgt = "[get_clocks -regexp -nocase {a a}]";
732    let ret = parser.parse(tgt).unwrap().0;
733    assert_eq!(
734        Object::GetClocks(GetClocks {
735            regexp: true,
736            nocase: true,
737            patterns: vec![String::from("a"), String::from("a")]
738        }),
739        ret
740    );
741    assert_eq!(tgt, format!("{}", ret));
742}
743
744// -----------------------------------------------------------------------------
745
746/// A type containing information of `get_lib_cells`
747#[derive(Clone, Debug, Default, PartialEq)]
748pub struct GetLibCells {
749    pub hsc: Option<String>,
750    pub regexp: bool,
751    pub nocase: bool,
752    pub patterns: Vec<String>,
753}
754
755impl fmt::Display for GetLibCells {
756    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
757        let mut args = String::from("");
758        if let Some(hsc) = &self.hsc {
759            args.push_str(&format!(" -hsc {}", hsc));
760        }
761        if self.regexp {
762            args.push_str(" -regexp");
763        }
764        if self.nocase {
765            args.push_str(" -nocase");
766        }
767        if self.patterns.len() == 1 {
768            args.push_str(&format!(" {}", self.patterns[0]));
769        } else if self.patterns.len() > 1 {
770            args.push_str(" {");
771            for (i, s) in self.patterns.iter().enumerate() {
772                if i == 0 {
773                    args.push_str(&format!("{}", s));
774                } else {
775                    args.push_str(&format!(" {}", s));
776                }
777            }
778            args.push_str("}");
779        }
780        write!(f, "[get_lib_cells{}]", args)
781    }
782}
783
784fn get_lib_cells<I>() -> impl Parser<Input = I, Output = Object>
785where
786    I: Stream<Item = char>,
787    I::Error: ParseError<I::Item, I::Range, I::Position>,
788{
789    let command = attempt(symbol("get_lib_cells")).or(symbol("get_lib_cell"));
790    let hsc = symbol("-hsc").with(item()).map(|x| ObjectArg::Hsc(x));
791    let regexp = symbol("-regexp").map(|_| ObjectArg::Regexp);
792    let nocase = symbol("-nocase").map(|_| ObjectArg::Nocase);
793    let patterns = choice((braces(parser(braces_strings)), item().map(|x| vec![x])))
794        .map(|x| ObjectArg::Patterns(x));
795    let args = (attempt(hsc), attempt(regexp), attempt(nocase), patterns);
796    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
797        let mut hsc = None;
798        let mut regexp = false;
799        let mut nocase = false;
800        let mut patterns = vec![];
801        for x in xs {
802            match x {
803                ObjectArg::Hsc(x) => hsc = Some(x),
804                ObjectArg::Regexp => regexp = true,
805                ObjectArg::Nocase => nocase = true,
806                ObjectArg::Patterns(x) => patterns = x,
807                _ => unreachable!(),
808            }
809        }
810        Object::GetLibCells(GetLibCells {
811            hsc,
812            regexp,
813            nocase,
814            patterns,
815        })
816    })
817}
818
819#[test]
820fn test_get_lib_cells() {
821    let mut parser = parser(object);
822    let tgt = "[get_lib_cells -hsc a -regexp -nocase a]";
823    let ret = parser.parse(tgt).unwrap().0;
824    assert_eq!(
825        Object::GetLibCells(GetLibCells {
826            hsc: Some(String::from("a")),
827            regexp: true,
828            nocase: true,
829            patterns: vec![String::from("a")]
830        }),
831        ret
832    );
833    assert_eq!(tgt, format!("{}", ret));
834
835    let tgt = "[get_lib_cells -hsc a -regexp -nocase {a a}]";
836    let ret = parser.parse(tgt).unwrap().0;
837    assert_eq!(
838        Object::GetLibCells(GetLibCells {
839            hsc: Some(String::from("a")),
840            regexp: true,
841            nocase: true,
842            patterns: vec![String::from("a"), String::from("a")]
843        }),
844        ret
845    );
846    assert_eq!(tgt, format!("{}", ret));
847}
848
849// -----------------------------------------------------------------------------
850
851/// A type containing information of `get_lib_pins`
852#[derive(Clone, Debug, Default, PartialEq)]
853pub struct GetLibPins {
854    pub regexp: bool,
855    pub nocase: bool,
856    pub patterns: Vec<String>,
857}
858
859impl fmt::Display for GetLibPins {
860    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
861        let mut args = String::from("");
862        if self.regexp {
863            args.push_str(" -regexp");
864        }
865        if self.nocase {
866            args.push_str(" -nocase");
867        }
868        if self.patterns.len() == 1 {
869            args.push_str(&format!(" {}", self.patterns[0]));
870        } else if self.patterns.len() > 1 {
871            args.push_str(" {");
872            for (i, s) in self.patterns.iter().enumerate() {
873                if i == 0 {
874                    args.push_str(&format!("{}", s));
875                } else {
876                    args.push_str(&format!(" {}", s));
877                }
878            }
879            args.push_str("}");
880        }
881        write!(f, "[get_lib_pins{}]", args)
882    }
883}
884
885fn get_lib_pins<I>() -> impl Parser<Input = I, Output = Object>
886where
887    I: Stream<Item = char>,
888    I::Error: ParseError<I::Item, I::Range, I::Position>,
889{
890    let command = attempt(symbol("get_lib_pins")).or(symbol("get_lib_pin"));
891    let regexp = symbol("-regexp").map(|_| ObjectArg::Regexp);
892    let nocase = symbol("-nocase").map(|_| ObjectArg::Nocase);
893    let patterns = choice((braces(parser(braces_strings)), item().map(|x| vec![x])))
894        .map(|x| ObjectArg::Patterns(x));
895    let args = (attempt(regexp), attempt(nocase), patterns);
896    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
897        let mut regexp = false;
898        let mut nocase = false;
899        let mut patterns = vec![];
900        for x in xs {
901            match x {
902                ObjectArg::Regexp => regexp = true,
903                ObjectArg::Nocase => nocase = true,
904                ObjectArg::Patterns(x) => patterns = x,
905                _ => unreachable!(),
906            }
907        }
908        Object::GetLibPins(GetLibPins {
909            regexp,
910            nocase,
911            patterns,
912        })
913    })
914}
915
916#[test]
917fn test_get_lib_pins() {
918    let mut parser = parser(object);
919    let tgt = "[get_lib_pins -regexp -nocase a]";
920    let ret = parser.parse(tgt).unwrap().0;
921    assert_eq!(
922        Object::GetLibPins(GetLibPins {
923            regexp: true,
924            nocase: true,
925            patterns: vec![String::from("a")]
926        }),
927        ret
928    );
929    assert_eq!(tgt, format!("{}", ret));
930
931    let tgt = "[get_lib_pins -regexp -nocase {a a}]";
932    let ret = parser.parse(tgt).unwrap().0;
933    assert_eq!(
934        Object::GetLibPins(GetLibPins {
935            regexp: true,
936            nocase: true,
937            patterns: vec![String::from("a"), String::from("a")]
938        }),
939        ret
940    );
941    assert_eq!(tgt, format!("{}", ret));
942}
943
944// -----------------------------------------------------------------------------
945
946/// A type containing information of `get_libs`
947#[derive(Clone, Debug, Default, PartialEq)]
948pub struct GetLibs {
949    pub regexp: bool,
950    pub nocase: bool,
951    pub patterns: Vec<String>,
952}
953
954impl fmt::Display for GetLibs {
955    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
956        let mut args = String::from("");
957        if self.regexp {
958            args.push_str(" -regexp");
959        }
960        if self.nocase {
961            args.push_str(" -nocase");
962        }
963        if self.patterns.len() == 1 {
964            args.push_str(&format!(" {}", self.patterns[0]));
965        } else if self.patterns.len() > 1 {
966            args.push_str(" {");
967            for (i, s) in self.patterns.iter().enumerate() {
968                if i == 0 {
969                    args.push_str(&format!("{}", s));
970                } else {
971                    args.push_str(&format!(" {}", s));
972                }
973            }
974            args.push_str("}");
975        }
976        write!(f, "[get_libs{}]", args)
977    }
978}
979
980fn get_libs<I>() -> impl Parser<Input = I, Output = Object>
981where
982    I: Stream<Item = char>,
983    I::Error: ParseError<I::Item, I::Range, I::Position>,
984{
985    let command = symbol("get_libs");
986    let regexp = symbol("-regexp").map(|_| ObjectArg::Regexp);
987    let nocase = symbol("-nocase").map(|_| ObjectArg::Nocase);
988    let patterns = choice((braces(parser(braces_strings)), item().map(|x| vec![x])))
989        .map(|x| ObjectArg::Patterns(x));
990    let args = (attempt(regexp), attempt(nocase), patterns);
991    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
992        let mut regexp = false;
993        let mut nocase = false;
994        let mut patterns = vec![];
995        for x in xs {
996            match x {
997                ObjectArg::Regexp => regexp = true,
998                ObjectArg::Nocase => nocase = true,
999                ObjectArg::Patterns(x) => patterns = x,
1000                _ => unreachable!(),
1001            }
1002        }
1003        Object::GetLibs(GetLibs {
1004            regexp,
1005            nocase,
1006            patterns,
1007        })
1008    })
1009}
1010
1011#[test]
1012fn test_get_libs() {
1013    let mut parser = parser(object);
1014    let tgt = "[get_libs -regexp -nocase a]";
1015    let ret = parser.parse(tgt).unwrap().0;
1016    assert_eq!(
1017        Object::GetLibs(GetLibs {
1018            regexp: true,
1019            nocase: true,
1020            patterns: vec![String::from("a")]
1021        }),
1022        ret
1023    );
1024    assert_eq!(tgt, format!("{}", ret));
1025
1026    let tgt = "[get_libs -regexp -nocase {a a}]";
1027    let ret = parser.parse(tgt).unwrap().0;
1028    assert_eq!(
1029        Object::GetLibs(GetLibs {
1030            regexp: true,
1031            nocase: true,
1032            patterns: vec![String::from("a"), String::from("a")]
1033        }),
1034        ret
1035    );
1036    assert_eq!(tgt, format!("{}", ret));
1037}
1038
1039// -----------------------------------------------------------------------------
1040
1041/// A type containing information of `get_nets`
1042#[derive(Clone, Debug, Default, PartialEq)]
1043pub struct GetNets {
1044    pub hierarchical: bool,
1045    pub hsc: Option<String>,
1046    pub regexp: bool,
1047    pub nocase: bool,
1048    pub of_objects: Option<Box<Object>>,
1049    pub patterns: Vec<String>,
1050}
1051
1052impl fmt::Display for GetNets {
1053    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1054        let mut args = String::from("");
1055        if self.hierarchical {
1056            args.push_str(" -hierarchical");
1057        }
1058        if let Some(hsc) = &self.hsc {
1059            args.push_str(&format!(" -hsc {}", hsc));
1060        }
1061        if self.regexp {
1062            args.push_str(" -regexp");
1063        }
1064        if self.nocase {
1065            args.push_str(" -nocase");
1066        }
1067        if let Some(of_objects) = &self.of_objects {
1068            args.push_str(&format!(" -of_objects {}", of_objects));
1069        }
1070        if self.patterns.len() == 1 {
1071            args.push_str(&format!(" {}", self.patterns[0]));
1072        } else if self.patterns.len() > 1 {
1073            args.push_str(" {");
1074            for (i, s) in self.patterns.iter().enumerate() {
1075                if i == 0 {
1076                    args.push_str(&format!("{}", s));
1077                } else {
1078                    args.push_str(&format!(" {}", s));
1079                }
1080            }
1081            args.push_str("}");
1082        }
1083        write!(f, "[get_nets{}]", args)
1084    }
1085}
1086
1087fn get_nets<I>() -> impl Parser<Input = I, Output = Object>
1088where
1089    I: Stream<Item = char>,
1090    I::Error: ParseError<I::Item, I::Range, I::Position>,
1091{
1092    let command = attempt(symbol("get_nets")).or(symbol("get_net"));
1093    let hierarchical = symbol("-hierarchical").map(|_| ObjectArg::Hierarchical);
1094    let hsc = symbol("-hsc").with(item()).map(|x| ObjectArg::Hsc(x));
1095    let regexp = symbol("-regexp").map(|_| ObjectArg::Regexp);
1096    let nocase = symbol("-nocase").map(|_| ObjectArg::Nocase);
1097    let of_objects = attempt(symbol("-of_objects"))
1098        .or(symbol("-of_object"))
1099        .with(parser(object))
1100        .map(|x| ObjectArg::OfObject(x));
1101    let patterns = choice((braces(parser(braces_strings)), item().map(|x| vec![x])))
1102        .map(|x| ObjectArg::Patterns(x));
1103    let args = (
1104        attempt(hierarchical),
1105        attempt(hsc),
1106        attempt(regexp),
1107        attempt(nocase),
1108        attempt(of_objects),
1109        patterns,
1110    );
1111    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
1112        let mut hierarchical = false;
1113        let mut hsc = None;
1114        let mut regexp = false;
1115        let mut nocase = false;
1116        let mut of_objects = None;
1117        let mut patterns = vec![];
1118        for x in xs {
1119            match x {
1120                ObjectArg::Hierarchical => hierarchical = true,
1121                ObjectArg::Hsc(x) => hsc = Some(x),
1122                ObjectArg::Regexp => regexp = true,
1123                ObjectArg::Nocase => nocase = true,
1124                ObjectArg::OfObject(x) => of_objects = Some(Box::new(x)),
1125                ObjectArg::Patterns(x) => patterns = x,
1126                _ => unreachable!(),
1127            }
1128        }
1129        Object::GetNets(GetNets {
1130            hierarchical,
1131            hsc,
1132            regexp,
1133            nocase,
1134            of_objects,
1135            patterns,
1136        })
1137    })
1138}
1139
1140#[test]
1141fn test_get_nets() {
1142    let mut parser = parser(object);
1143    let tgt = "[get_nets -hierarchical -hsc a -regexp -nocase -of_objects a a]";
1144    let ret = parser.parse(tgt).unwrap().0;
1145    assert_eq!(
1146        Object::GetNets(GetNets {
1147            hierarchical: true,
1148            hsc: Some(String::from("a")),
1149            regexp: true,
1150            nocase: true,
1151            of_objects: Some(Box::new(Object::String(ObjectString {
1152                strings: vec![String::from("a")]
1153            }))),
1154            patterns: vec![String::from("a")]
1155        }),
1156        ret
1157    );
1158    assert_eq!(tgt, format!("{}", ret));
1159
1160    let tgt = "[get_nets -hierarchical -hsc a -regexp -nocase -of_objects a {a a}]";
1161    let ret = parser.parse(tgt).unwrap().0;
1162    assert_eq!(
1163        Object::GetNets(GetNets {
1164            hierarchical: true,
1165            hsc: Some(String::from("a")),
1166            regexp: true,
1167            nocase: true,
1168            of_objects: Some(Box::new(Object::String(ObjectString {
1169                strings: vec![String::from("a")]
1170            }))),
1171            patterns: vec![String::from("a"), String::from("a")]
1172        }),
1173        ret
1174    );
1175    assert_eq!(tgt, format!("{}", ret));
1176}
1177
1178// -----------------------------------------------------------------------------
1179
1180/// A type containing information of `get_pins`
1181#[derive(Clone, Debug, Default, PartialEq)]
1182pub struct GetPins {
1183    pub hierarchical: bool,
1184    pub hsc: Option<String>,
1185    pub regexp: bool,
1186    pub nocase: bool,
1187    pub of_objects: Option<Box<Object>>,
1188    pub patterns: Vec<String>,
1189}
1190
1191impl fmt::Display for GetPins {
1192    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1193        let mut args = String::from("");
1194        if self.hierarchical {
1195            args.push_str(" -hierarchical");
1196        }
1197        if let Some(hsc) = &self.hsc {
1198            args.push_str(&format!(" -hsc {}", hsc));
1199        }
1200        if self.regexp {
1201            args.push_str(" -regexp");
1202        }
1203        if self.nocase {
1204            args.push_str(" -nocase");
1205        }
1206        if let Some(of_objects) = &self.of_objects {
1207            args.push_str(&format!(" -of_objects {}", of_objects));
1208        }
1209        if self.patterns.len() == 1 {
1210            args.push_str(&format!(" {}", self.patterns[0]));
1211        } else if self.patterns.len() > 1 {
1212            args.push_str(" {");
1213            for (i, s) in self.patterns.iter().enumerate() {
1214                if i == 0 {
1215                    args.push_str(&format!("{}", s));
1216                } else {
1217                    args.push_str(&format!(" {}", s));
1218                }
1219            }
1220            args.push_str("}");
1221        }
1222        write!(f, "[get_pins{}]", args)
1223    }
1224}
1225
1226fn get_pins<I>() -> impl Parser<Input = I, Output = Object>
1227where
1228    I: Stream<Item = char>,
1229    I::Error: ParseError<I::Item, I::Range, I::Position>,
1230{
1231    let command = attempt(symbol("get_pins")).or(symbol("get_pin"));
1232    let hierarchical = symbol("-hierarchical").map(|_| ObjectArg::Hierarchical);
1233    let hsc = symbol("-hsc").with(item()).map(|x| ObjectArg::Hsc(x));
1234    let regexp = symbol("-regexp").map(|_| ObjectArg::Regexp);
1235    let nocase = symbol("-nocase").map(|_| ObjectArg::Nocase);
1236    let of_objects = attempt(symbol("-of_objects"))
1237        .or(symbol("-of_object"))
1238        .with(parser(object))
1239        .map(|x| ObjectArg::OfObject(x));
1240    let patterns = choice((braces(parser(braces_strings)), item().map(|x| vec![x])))
1241        .map(|x| ObjectArg::Patterns(x));
1242    let args = (
1243        attempt(hierarchical),
1244        attempt(hsc),
1245        attempt(regexp),
1246        attempt(nocase),
1247        attempt(of_objects),
1248        patterns,
1249    );
1250    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
1251        let mut hierarchical = false;
1252        let mut hsc = None;
1253        let mut regexp = false;
1254        let mut nocase = false;
1255        let mut of_objects = None;
1256        let mut patterns = vec![];
1257        for x in xs {
1258            match x {
1259                ObjectArg::Hierarchical => hierarchical = true,
1260                ObjectArg::Hsc(x) => hsc = Some(x),
1261                ObjectArg::Regexp => regexp = true,
1262                ObjectArg::Nocase => nocase = true,
1263                ObjectArg::OfObject(x) => of_objects = Some(Box::new(x)),
1264                ObjectArg::Patterns(x) => patterns = x,
1265                _ => unreachable!(),
1266            }
1267        }
1268        Object::GetPins(GetPins {
1269            hierarchical,
1270            hsc,
1271            regexp,
1272            nocase,
1273            of_objects,
1274            patterns,
1275        })
1276    })
1277}
1278
1279#[test]
1280fn test_get_pins() {
1281    let mut parser = parser(object);
1282    let tgt = "[get_pins -hierarchical -hsc a -regexp -nocase -of_objects a a]";
1283    let ret = parser.parse(tgt).unwrap().0;
1284    assert_eq!(
1285        Object::GetPins(GetPins {
1286            hierarchical: true,
1287            hsc: Some(String::from("a")),
1288            regexp: true,
1289            nocase: true,
1290            of_objects: Some(Box::new(Object::String(ObjectString {
1291                strings: vec![String::from("a")]
1292            }))),
1293            patterns: vec![String::from("a")]
1294        }),
1295        ret
1296    );
1297    assert_eq!(tgt, format!("{}", ret));
1298
1299    let tgt = "[get_pins -hierarchical -hsc a -regexp -nocase -of_objects a {a a}]";
1300    let ret = parser.parse(tgt).unwrap().0;
1301    assert_eq!(
1302        Object::GetPins(GetPins {
1303            hierarchical: true,
1304            hsc: Some(String::from("a")),
1305            regexp: true,
1306            nocase: true,
1307            of_objects: Some(Box::new(Object::String(ObjectString {
1308                strings: vec![String::from("a")]
1309            }))),
1310            patterns: vec![String::from("a"), String::from("a")]
1311        }),
1312        ret
1313    );
1314    assert_eq!(tgt, format!("{}", ret));
1315}
1316
1317// -----------------------------------------------------------------------------
1318
1319/// A type containing information of `get_ports`
1320#[derive(Clone, Debug, Default, PartialEq)]
1321pub struct GetPorts {
1322    pub regexp: bool,
1323    pub nocase: bool,
1324    pub patterns: Vec<String>,
1325}
1326
1327impl fmt::Display for GetPorts {
1328    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1329        let mut args = String::from("");
1330        if self.regexp {
1331            args.push_str(" -regexp");
1332        }
1333        if self.nocase {
1334            args.push_str(" -nocase");
1335        }
1336        if self.patterns.len() == 1 {
1337            args.push_str(&format!(" {}", self.patterns[0]));
1338        } else if self.patterns.len() > 1 {
1339            args.push_str(" {");
1340            for (i, s) in self.patterns.iter().enumerate() {
1341                if i == 0 {
1342                    args.push_str(&format!("{}", s));
1343                } else {
1344                    args.push_str(&format!(" {}", s));
1345                }
1346            }
1347            args.push_str("}");
1348        }
1349        write!(f, "[get_ports{}]", args)
1350    }
1351}
1352
1353fn get_ports<I>() -> impl Parser<Input = I, Output = Object>
1354where
1355    I: Stream<Item = char>,
1356    I::Error: ParseError<I::Item, I::Range, I::Position>,
1357{
1358    let command = attempt(symbol("get_ports")).or(symbol("get_port"));
1359    let regexp = symbol("-regexp").map(|_| ObjectArg::Regexp);
1360    let nocase = symbol("-nocase").map(|_| ObjectArg::Nocase);
1361    let patterns = choice((braces(parser(braces_strings)), item().map(|x| vec![x])))
1362        .map(|x| ObjectArg::Patterns(x));
1363    let args = (attempt(regexp), attempt(nocase), patterns);
1364    brackets(command.with(many(choice(args)))).map(|xs: Vec<_>| {
1365        let mut regexp = false;
1366        let mut nocase = false;
1367        let mut patterns = vec![];
1368        for x in xs {
1369            match x {
1370                ObjectArg::Regexp => regexp = true,
1371                ObjectArg::Nocase => nocase = true,
1372                ObjectArg::Patterns(x) => patterns = x,
1373                _ => unreachable!(),
1374            }
1375        }
1376        Object::GetPorts(GetPorts {
1377            regexp,
1378            nocase,
1379            patterns,
1380        })
1381    })
1382}
1383
1384#[test]
1385fn test_get_ports() {
1386    let mut parser = parser(object);
1387    let tgt = "[get_ports -regexp -nocase a]";
1388    let ret = parser.parse(tgt).unwrap().0;
1389    assert_eq!(
1390        Object::GetPorts(GetPorts {
1391            regexp: true,
1392            nocase: true,
1393            patterns: vec![String::from("a")]
1394        }),
1395        ret
1396    );
1397    assert_eq!(tgt, format!("{}", ret));
1398
1399    let tgt = "[get_ports -regexp -nocase {a a}]";
1400    let ret = parser.parse(tgt).unwrap().0;
1401    assert_eq!(
1402        Object::GetPorts(GetPorts {
1403            regexp: true,
1404            nocase: true,
1405            patterns: vec![String::from("a"), String::from("a")]
1406        }),
1407        ret
1408    );
1409    assert_eq!(tgt, format!("{}", ret));
1410}
1411
1412// -----------------------------------------------------------------------------
1413
1414/// A type containing information of `list`
1415#[derive(Clone, Debug, Default, PartialEq)]
1416pub struct List {
1417    pub objects: Vec<Object>,
1418}
1419
1420impl fmt::Display for List {
1421    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1422        let mut args = String::from("");
1423        for s in &self.objects {
1424            args.push_str(&format!(" {}", s));
1425        }
1426        write!(f, "[list{}]", args)
1427    }
1428}
1429
1430fn list<I>() -> impl Parser<Input = I, Output = Object>
1431where
1432    I: Stream<Item = char>,
1433    I::Error: ParseError<I::Item, I::Range, I::Position>,
1434{
1435    let command = symbol("list");
1436    brackets(command.with(many1(parser(object)))).map(|x| Object::List(List { objects: x }))
1437}
1438
1439#[test]
1440fn test_list() {
1441    let mut parser = parser(object);
1442    let tgt = "[list [all_inputs] [all_outputs]]";
1443    let ret = parser.parse(tgt).unwrap().0;
1444    assert_eq!(
1445        Object::List(List {
1446            objects: vec![
1447                Object::AllInputs(AllInputs {
1448                    level_sensitive: false,
1449                    edge_triggered: false,
1450                    clock: None
1451                }),
1452                Object::AllOutputs(AllOutputs {
1453                    level_sensitive: false,
1454                    edge_triggered: false,
1455                    clock: None
1456                }),
1457            ]
1458        }),
1459        ret
1460    );
1461    assert_eq!(tgt, format!("{}", ret));
1462}
1463
1464// -----------------------------------------------------------------------------
1465
1466/// A string type
1467#[derive(Clone, Debug, Default, PartialEq)]
1468pub struct ObjectString {
1469    pub strings: Vec<String>,
1470}
1471
1472impl fmt::Display for ObjectString {
1473    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1474        let mut ret = String::from("");
1475        if self.strings.len() == 0 {
1476        } else if self.strings.len() == 1 {
1477            if self.strings[0].chars().any(|x| x.is_whitespace()) {
1478                ret.push_str(&format!("\"{}\"", self.strings[0]))
1479            } else {
1480                ret.push_str(&self.strings[0])
1481            }
1482        } else {
1483            ret.push_str("{");
1484            for (i, s) in self.strings.iter().enumerate() {
1485                if i != 0 {
1486                    ret.push_str(" ");
1487                }
1488                if s.chars().any(|x| x.is_whitespace()) {
1489                    ret.push_str(&format!("\"{}\"", s));
1490                } else {
1491                    ret.push_str(&format!("{}", s));
1492                }
1493            }
1494            ret.push_str("}");
1495        }
1496        write!(f, "{}", ret)
1497    }
1498}
1499
1500fn string<I>() -> impl Parser<Input = I, Output = Object>
1501where
1502    I: Stream<Item = char>,
1503    I::Error: ParseError<I::Item, I::Range, I::Position>,
1504{
1505    choice((
1506        braces(parser(braces_strings).map(|x| Object::String(ObjectString { strings: x }))),
1507        item().map(|x| Object::String(ObjectString { strings: vec![x] })),
1508    ))
1509}
1510
1511#[test]
1512fn test_string() {
1513    let mut parser = parser(object);
1514    let tgt = "a";
1515    let ret = parser.parse(tgt).unwrap().0;
1516    assert_eq!(
1517        Object::String(ObjectString {
1518            strings: vec![String::from("a")]
1519        }),
1520        ret
1521    );
1522    assert_eq!(tgt, format!("{}", ret));
1523
1524    let tgt = "{a b c}";
1525    let ret = parser.parse(tgt).unwrap().0;
1526    assert_eq!(
1527        Object::String(ObjectString {
1528            strings: vec![String::from("a"), String::from("b"), String::from("c")]
1529        }),
1530        ret
1531    );
1532    assert_eq!(tgt, format!("{}", ret));
1533
1534    let tgt = "\"a b c\"";
1535    let ret = parser.parse(tgt).unwrap().0;
1536    assert_eq!(
1537        Object::String(ObjectString {
1538            strings: vec![String::from("a b c")]
1539        }),
1540        ret
1541    );
1542    assert_eq!(tgt, format!("{}", ret));
1543}