ICFP 2007 Contest: https://web.archive.org/web/20090301164728/https://save-endo.cs.uu.nl/

Display for Pattern, in preparation of disassembly

Changed files
+103 -6
dna2rna
+5 -5
dna2rna/src/parser.rs
···
{
self.advance(3);
if level == 0 {
-
return Some(ret);
+
return Some(Pattern::new(ret));
}
level -= 1;
ret.push(PatternItem::Close);
···
let mut parser = Parser::new(dna);
assert_eq!(
parser.pattern(&mut rna),
-
Some(vec![PatternItem::Base(Base::I)])
+
Some(Pattern::new(vec![PatternItem::Base(Base::I)]))
);
assert_eq!(parser.index, 4);
···
let mut parser = Parser::new(dna);
assert_eq!(
parser.pattern(&mut rna),
-
Some(vec![
+
Some(Pattern::new(vec![
PatternItem::Open,
PatternItem::Skip(2),
PatternItem::Close,
PatternItem::Base(Base::P)
-
])
+
]))
);
assert_eq!(parser.index, 16);
let dna = dna_from_str("IIIPFCICFPIIC").into_iter();
let mut parser = Parser::new(dna);
-
assert_eq!(parser.pattern(&mut rna), Some(vec![]));
+
assert_eq!(parser.pattern(&mut rna), Some(Pattern::new(vec![])));
assert_eq!(parser.index, 13);
assert_eq!(
rna,
+98 -1
dna2rna/src/pattern.rs
···
use crate::dna::Base;
+
use std::fmt;
+
use std::slice::Iter;
#[derive(Debug, PartialEq)]
pub enum PatternItem {
···
Close,
}
-
pub type Pattern = Vec<PatternItem>;
+
impl fmt::Display for PatternItem {
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+
match &self {
+
PatternItem::Base(b) => write!(f, "{}", b.to_char()),
+
PatternItem::Skip(n) => write!(f, "!{{{}}}", n),
+
PatternItem::Search(s) => {
+
write!(f, "?{{")?;
+
for b in s {
+
write!(f, "{}", b.to_char())?;
+
}
+
write!(f, "}}")?;
+
Ok(())
+
}
+
PatternItem::Open => write!(f, "("),
+
PatternItem::Close => write!(f, ")"),
+
}
+
}
+
}
+
+
#[derive(PartialEq, Debug)]
+
pub struct Pattern {
+
pattern: Vec<PatternItem>,
+
}
+
+
impl Pattern {
+
pub fn new(pattern: Vec<PatternItem>) -> Pattern {
+
Pattern { pattern: pattern }
+
}
+
+
pub fn iter<'a>(&'a self) -> Iter<'a, PatternItem> {
+
self.pattern.iter()
+
}
+
}
+
+
impl fmt::Display for Pattern {
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+
for p in self.iter() {
+
write!(f, "{}", p)?;
+
}
+
Ok(())
+
}
+
}
+
+
#[cfg(test)]
+
mod tests {
+
use super::*;
+
+
#[test]
+
fn test_display_base() {
+
assert_eq!(
+
Pattern::new(vec![
+
PatternItem::Base(Base::I),
+
PatternItem::Base(Base::C),
+
PatternItem::Base(Base::F),
+
PatternItem::Base(Base::P)
+
])
+
.to_string(),
+
"ICFP"
+
);
+
}
+
+
#[test]
+
fn test_display_skip() {
+
assert_eq!(Pattern::new(vec![PatternItem::Skip(5)]).to_string(), "!{5}");
+
}
+
+
#[test]
+
fn test_display_search() {
+
assert_eq!(
+
Pattern::new(vec![PatternItem::Search(vec![
+
Base::I,
+
Base::C,
+
Base::F,
+
Base::P
+
])])
+
.to_string(),
+
"?{ICFP}"
+
);
+
}
+
+
#[test]
+
fn test_display_group() {
+
assert_eq!(
+
Pattern::new(vec![
+
PatternItem::Open,
+
PatternItem::Base(Base::I),
+
PatternItem::Base(Base::C),
+
PatternItem::Base(Base::F),
+
PatternItem::Base(Base::P),
+
PatternItem::Close,
+
])
+
.to_string(),
+
"(ICFP)"
+
)
+
}
+
}