1use std::fmt;
2
3#[derive(Debug, PartialEq, Eq, Clone, Copy)]
4pub enum Instruction {
5 Right(usize),
7 Left(usize),
9 Increment(usize),
11 Decrement(usize),
13 Write,
15 Read,
17 JumpForwardIfZero {
19 matching: Option<usize>,
22 },
23 JumpBackwardUnlessZero {
25 matching: usize,
28 },
29}
30
31impl fmt::Display for Instruction {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 f.write_str(match *self {
34 Instruction::Right(n) => format_instruction(">", n),
35 Instruction::Left(n) => format_instruction("<", n),
36 Instruction::Increment(n) => format_instruction("+", n),
37 Instruction::Decrement(n) => format_instruction("-", n),
38 Instruction::Write => ".".to_owned(),
39 Instruction::Read => ",".to_owned(),
40 Instruction::JumpForwardIfZero { .. } => "[".to_owned(),
41 Instruction::JumpBackwardUnlessZero { .. } => "]".to_owned(),
42 }.as_ref())
43 }
44}
45
46#[inline]
47fn format_instruction(instr: &str, n: usize) -> String {
48 format!("{}{}", instr, if n > 1 {format!("{}", n)} else {"".to_owned()})
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn display() {
57 assert_eq!(Instruction::Right(1).to_string(), ">");
58 assert_eq!(Instruction::Right(2).to_string(), ">2");
59 assert_eq!(Instruction::Right(5).to_string(), ">5");
60
61 assert_eq!(Instruction::Left(1).to_string(), "<");
62 assert_eq!(Instruction::Left(2).to_string(), "<2");
63 assert_eq!(Instruction::Left(5).to_string(), "<5");
64
65 assert_eq!(Instruction::Increment(1).to_string(), "+");
66 assert_eq!(Instruction::Increment(2).to_string(), "+2");
67 assert_eq!(Instruction::Increment(5).to_string(), "+5");
68
69 assert_eq!(Instruction::Decrement(1).to_string(), "-");
70 assert_eq!(Instruction::Decrement(2).to_string(), "-2");
71 assert_eq!(Instruction::Decrement(5).to_string(), "-5");
72
73 assert_eq!(Instruction::Write.to_string(), ".");
74 assert_eq!(Instruction::Read.to_string(), ",");
75
76 assert_eq!(Instruction::JumpForwardIfZero {matching: None}.to_string(), "[");
77 assert_eq!(Instruction::JumpBackwardUnlessZero {matching: 0}.to_string(), "]");
78 }
79}