use sonor::Speaker; use std::time::Duration; type Result = std::result::Result; #[tokio::main] async fn main() -> Result<()> { let roomname = std::env::args() .nth(1) .expect("expected room name as first argument"); let speaker = sonor::find(&roomname, Duration::from_secs(3)) .await? .unwrap_or_else(|| panic!("speaker '{}' doesn't exist", roomname)); general(&speaker).await?; currently_playing(&speaker).await?; equalizer(&speaker).await?; group_state(&speaker).await?; Ok(()) } async fn general(speaker: &Speaker) -> Result<()> { println!("Name: {}", speaker.name().await?); Ok(()) } async fn currently_playing(speaker: &Speaker) -> Result<()> { println!(); let track_info = speaker.track().await?; if let Some(track_info) = track_info { let duration = fmt_duration(track_info.duration()); let elapsed = fmt_duration(track_info.elapsed()); println!( "Currently playing: '{}' [{}/{}]", track_info.track(), elapsed, duration ); } else { println!("No track are currently playing..."); return Ok(()); } let queue = &speaker.queue().await?; match queue.len() { 0 => println!("There are no tracks coming after that."), 1 => println!("1 track in queue:"), n => println!("{} tracks in queue:", n), } for track in queue.iter().take(5) { println!(" - {}", track); } if queue.len() > 5 { println!(" - ..."); } Ok(()) } async fn equalizer(_speaker: &Speaker) -> Result<()> { Ok(()) } async fn group_state(speaker: &Speaker) -> Result<()> { let groups: Vec<_> = speaker .zone_group_state() .await? .into_iter() .filter(|(_, speakers)| speakers.len() > 1) .collect(); if groups.is_empty() { return Ok(()); } println!(); println!("Groups: "); for (coordinator, speakers) in groups { let coordinator = speakers .iter() .find(|s| s.uuid().eq_ignore_ascii_case(&coordinator)) .expect("no coordinator for group"); println!(" - {}", coordinator.name()); for speaker in speakers { println!(" - {} : {}", speaker.name(), speaker.uuid()); } } Ok(()) } fn fmt_duration(secs: u32) -> String { format!("{:02}:{:02}", secs / 60, secs % 60) }