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#[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
84enum 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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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}