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}