use std::fmt;
use crate::core::Fraction;
use super::base::{MusicElement, Stream};
#[derive(Debug, Clone)]
pub struct Voice {
id: u8,
stream: Stream,
}
impl Voice {
pub fn new(id: u8) -> Self {
Self {
id,
stream: Stream::new(),
}
}
pub fn id(&self) -> u8 {
self.id
}
pub fn set_id(&mut self, id: u8) {
self.id = id;
}
pub fn stream(&self) -> &Stream {
&self.stream
}
pub fn stream_mut(&mut self) -> &mut Stream {
&mut self.stream
}
pub fn elements(&self) -> &[(Fraction, MusicElement)] {
self.stream.elements()
}
pub fn append(&mut self, element: MusicElement) {
self.stream.append(element);
}
pub fn insert(&mut self, offset: Fraction, element: MusicElement) {
self.stream.insert(offset, element);
}
pub fn duration(&self) -> Fraction {
self.stream.duration()
}
pub fn len(&self) -> usize {
self.stream.len()
}
pub fn is_empty(&self) -> bool {
self.stream.is_empty()
}
pub fn clear(&mut self) {
self.stream.clear();
}
pub fn notes(&self) -> impl Iterator<Item = &crate::core::Note> {
self.stream.notes()
}
}
impl Default for Voice {
fn default() -> Self {
Self::new(1)
}
}
impl fmt::Display for Voice {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Voice {} ({} elements)", self.id, self.len())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::{Note, Pitch, Step};
#[test]
fn test_voice_creation() {
let voice = Voice::new(1);
assert_eq!(voice.id(), 1);
assert!(voice.is_empty());
}
#[test]
fn test_voice_append() {
let mut voice = Voice::new(1);
let note = Note::quarter(Pitch::from_parts(Step::C, Some(4), None));
voice.append(MusicElement::Note(note));
assert_eq!(voice.len(), 1);
}
}