ICFP 2007 Contest: https://web.archive.org/web/20090301164728/https://save-endo.cs.uu.nl/
1use crate::base::Base;
2use std::fmt;
3use std::slice;
4use std::vec;
5
6#[derive(Debug, PartialEq)]
7pub enum PatternItem {
8 Base(Base),
9 Skip(usize),
10 Search(Vec<Base>),
11 Open,
12 Close,
13}
14
15impl fmt::Display for PatternItem {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 match &self {
18 PatternItem::Base(b) => write!(f, "{}", b.to_char()),
19 PatternItem::Skip(n) => write!(f, "!{{{}}}", n),
20 PatternItem::Search(s) => {
21 write!(f, "?{{")?;
22 for b in s {
23 write!(f, "{}", b.to_char())?;
24 }
25 write!(f, "}}")?;
26 Ok(())
27 }
28 PatternItem::Open => write!(f, "("),
29 PatternItem::Close => write!(f, ")"),
30 }
31 }
32}
33
34#[derive(PartialEq, Debug)]
35pub struct Pattern {
36 pattern: Vec<PatternItem>,
37}
38
39impl Pattern {
40 pub fn new(pattern: Vec<PatternItem>) -> Pattern {
41 Pattern { pattern: pattern }
42 }
43
44 pub fn iter<'a>(&'a self) -> slice::Iter<'a, PatternItem> {
45 self.pattern.iter()
46 }
47
48 pub fn into_iter<'a>(self) -> vec::IntoIter<PatternItem> {
49 self.pattern.into_iter()
50 }
51}
52
53impl fmt::Display for Pattern {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 for p in self.iter() {
56 write!(f, "{}", p)?;
57 }
58 Ok(())
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_display_base() {
68 assert_eq!(
69 Pattern::new(vec![
70 PatternItem::Base(Base::I),
71 PatternItem::Base(Base::C),
72 PatternItem::Base(Base::F),
73 PatternItem::Base(Base::P)
74 ])
75 .to_string(),
76 "ICFP"
77 );
78 }
79
80 #[test]
81 fn test_display_skip() {
82 assert_eq!(Pattern::new(vec![PatternItem::Skip(5)]).to_string(), "!{5}");
83 }
84
85 #[test]
86 fn test_display_search() {
87 assert_eq!(
88 Pattern::new(vec![PatternItem::Search(vec![
89 Base::I,
90 Base::C,
91 Base::F,
92 Base::P
93 ])])
94 .to_string(),
95 "?{ICFP}"
96 );
97 }
98
99 #[test]
100 fn test_display_group() {
101 assert_eq!(
102 Pattern::new(vec![
103 PatternItem::Open,
104 PatternItem::Base(Base::I),
105 PatternItem::Base(Base::C),
106 PatternItem::Base(Base::F),
107 PatternItem::Base(Base::P),
108 PatternItem::Close,
109 ])
110 .to_string(),
111 "(ICFP)"
112 )
113 }
114}