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 TemplateItem {
8 Base(Base),
9 Ref(usize, usize),
10 Len(usize),
11}
12
13impl fmt::Display for TemplateItem {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 match &self {
16 TemplateItem::Base(b) => write!(f, "{}", b.to_char()),
17 TemplateItem::Ref(n, l) => {
18 if *l == 0 {
19 write!(f, "{{{}}}", n)
20 } else {
21 write!(f, "{{{},{}}}", n, l)
22 }
23 }
24 TemplateItem::Len(n) => {
25 write!(f, "|{}|", n)
26 }
27 }
28 }
29}
30
31#[derive(Debug, PartialEq)]
32pub struct Template {
33 template: Vec<TemplateItem>,
34}
35
36impl Template {
37 pub fn new(template: Vec<TemplateItem>) -> Template {
38 Template { template: template }
39 }
40
41 pub fn iter<'a>(&'a self) -> slice::Iter<'a, TemplateItem> {
42 self.template.iter()
43 }
44
45 pub fn into_iter<'a>(self) -> vec::IntoIter<TemplateItem> {
46 self.template.into_iter()
47 }
48}
49
50impl fmt::Display for Template {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 for p in self.iter() {
53 write!(f, "{}", p)?;
54 }
55 Ok(())
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_display_base() {
65 assert_eq!(
66 Template::new(vec![
67 TemplateItem::Base(Base::I),
68 TemplateItem::Base(Base::C),
69 TemplateItem::Base(Base::F),
70 TemplateItem::Base(Base::P)
71 ])
72 .to_string(),
73 "ICFP"
74 );
75 }
76
77 #[test]
78 fn test_display_ref() {
79 assert_eq!(
80 Template::new(vec![TemplateItem::Ref(3, 2), TemplateItem::Ref(4, 0),]).to_string(),
81 "{3,2}{4}"
82 );
83 }
84
85 #[test]
86 fn test_display_lenf() {
87 assert_eq!(Template::new(vec![TemplateItem::Len(3)]).to_string(), "|3|");
88 }
89}