diff --git a/src/seq.rs b/src/seq.rs index f8804a8..80a4692 100644 --- a/src/seq.rs +++ b/src/seq.rs @@ -1,8 +1,9 @@ -use crate::tone::Tone; +use crate::tone; use crate::syn; +#[derive(PartialEq)] struct Seq { - beats: Vec<(i32, Tone)>, + beats: Vec<(i32, tone::Tone)>, } pub fn new() -> Seq { @@ -16,6 +17,54 @@ impl Seq { } } - pub fn append(s: S) { + pub fn pop(&mut self) -> Option { + match self.beats.len() { + 0 => None, + _ => match self.beats[0].0 { + 1 => Some(self.beats.remove(0).1), + _ => { + self.beats[0].0 -= 1; + Some(self.beats[0].1.clone()) + }, + }, + } + } + + pub fn append(&mut self, s: S) { + self.append_one(s.to_string()); + } + + fn append_one(&mut self, s: String) { + let re = regex::Regex::new(r"^(?[0-9]*)(?[a-z].*)$").unwrap(); + let captures = re.captures(&s).unwrap(); + + let n = match captures.name("count") { + Some(number) if number.as_str().len() > 0 => number.as_str().parse::().unwrap(), + _ => 1, + } as i32; + + let tone = tone::new(captures.name("tone").unwrap().as_str()); + self.beats.push((n, tone)); + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_seq() { + let mut seq = new(); + seq.append("c"); + seq.append("4d"); + assert_eq!(seq.beats.len(), 2); + assert_eq!(seq.beats[0], (1 as i32, tone::new("c"))); + assert_eq!(seq.beats[1], (4 as i32, tone::new("d"))); + + assert_eq!(seq.pop(), Some(tone::new("c"))); + for _ in 0..4 { + assert_eq!(seq.pop(), Some(tone::new("d"))); + } + assert_eq!(seq.pop(), None); } } diff --git a/src/tone.rs b/src/tone.rs index 9fb18a6..2a0f7df 100644 --- a/src/tone.rs +++ b/src/tone.rs @@ -1,4 +1,4 @@ -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct Tone(i32); // new parses [a-g][+-]?[1-5]? to tone, sharp or flat, down 2 octave..up 1 octave