use serde::{Deserialize, Serialize}; use std::fmt::Display; mod displayutil; mod effects; mod tempo; mod voices; pub use effects::{display_effects, generate_effects, Effect}; pub use tempo::Tempo; pub use voices::{generate_voice_adjective, Voice, display_voices}; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct SongIdea { pub tempo: Tempo, pub effects: Vec, pub lead: Option, pub bass: Option, pub pad: Option, pub vocals: Option, pub kick: Option, pub snare: Option, pub hat: Option, pub tom: Option, pub cymbal: Option, } impl SongIdea { pub fn generate() -> Self { Self { tempo: rand::random(), effects: generate_effects(), lead: generate_voice_adjective("lead"), bass: generate_voice_adjective("bass"), pad: generate_voice_adjective("pad"), vocals: generate_voice_adjective("vocals"), kick: generate_voice_adjective("kick"), snare: generate_voice_adjective("snare"), hat: generate_voice_adjective("hat"), tom: generate_voice_adjective("tom"), cymbal: generate_voice_adjective("cymbal") } } pub fn generate_ambient() -> Self { Self { tempo: rand::random(), effects: generate_effects(), lead: generate_voice_adjective("lead"), bass: generate_voice_adjective("bass"), pad: generate_voice_adjective("pad"), vocals: generate_voice_adjective("vocals"), kick: None, snare: None, hat: None, tom: None, cymbal: None } } } impl Display for SongIdea { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { let voices: Vec<_> = [&self.lead, &self.bass, &self.pad, &self.vocals, &self.kick, &self.snare, &self.hat, &self.tom, &self.cymbal].iter().cloned().cloned().filter_map(|voice| voice).collect(); write!(fmt, "{} at {}, {}", display_voices(&voices), self.tempo, display_effects(&self.effects)) } }