From 654a403459fb1f59ca6a4339bd7cedba2b78237d Mon Sep 17 00:00:00 2001 From: Paul Lietar Date: Tue, 29 Dec 2015 23:12:02 +0100 Subject: [PATCH] Improve handling of missing audio keys by failing the future rather than crashing. --- src/audio_key.rs | 40 ++++++++++++++++++++++++++++------------ src/metadata.rs | 4 ++-- src/session.rs | 4 ++-- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/audio_key.rs b/src/audio_key.rs index bdd5db1a..d068af8f 100644 --- a/src/audio_key.rs +++ b/src/audio_key.rs @@ -9,13 +9,16 @@ use session::Session; use connection::PacketHandler; pub type AudioKey = [u8; 16]; +#[derive(Debug,Hash,PartialEq,Eq,Copy,Clone)] +pub struct AudioKeyError; #[derive(Debug,Hash,PartialEq,Eq,Clone)] struct AudioKeyId(SpotifyId, FileId); enum AudioKeyStatus { - Loading(Vec>), - Loaded(AudioKey) + Loading(Vec>), + Loaded(AudioKey), + Failed(AudioKeyError) } pub struct AudioKeyManager { @@ -34,12 +37,15 @@ impl AudioKeyManager { } pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId) - -> eventual::Future { + -> eventual::Future { let id = AudioKeyId(track, file); self.cache.get_mut(&id).map(|status| match *status { + AudioKeyStatus::Failed(error) => { + eventual::Future::error(error) + } AudioKeyStatus::Loaded(key) => { - eventual::Future::of(key.clone()) + eventual::Future::of(key) } AudioKeyStatus::Loading(ref mut req) => { let (tx, rx) = eventual::Future::pair(); @@ -69,19 +75,29 @@ impl AudioKeyManager { impl PacketHandler for AudioKeyManager { fn handle(&mut self, cmd: u8, data: Vec) { - assert_eq!(cmd, 0xd); - let mut data = Cursor::new(data); let seq = data.read_u32::().unwrap(); - let mut key = [0u8; 16]; - data.read_exact(&mut key).unwrap(); if let Some(status) = self.pending.remove(&seq).and_then(|id| { self.cache.get_mut(&id) }) { - let status = mem::replace(status, AudioKeyStatus::Loaded(key)); + if cmd == 0xd { + let mut key = [0u8; 16]; + data.read_exact(&mut key).unwrap(); - if let AudioKeyStatus::Loading(cbs) = status { - for cb in cbs { - cb.complete(key); + let status = mem::replace(status, AudioKeyStatus::Loaded(key)); + + if let AudioKeyStatus::Loading(cbs) = status { + for cb in cbs { + cb.complete(key); + } + } + } else if cmd == 0xe { + let error = AudioKeyError; + let status = mem::replace(status, AudioKeyStatus::Failed(error)); + + if let AudioKeyStatus::Loading(cbs) = status { + for cb in cbs { + cb.fail(error); + } } } } diff --git a/src/metadata.rs b/src/metadata.rs index f9c50e24..37e70c54 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -92,7 +92,7 @@ impl MetadataTrait for Album { "hm://metadata/3/album" } - fn parse(msg: &Self::Message, session: &Session) -> Self { + fn parse(msg: &Self::Message, _: &Session) -> Self { Album { id: SpotifyId::from_raw(msg.get_gid()), name: msg.get_name().to_owned(), @@ -118,7 +118,7 @@ impl MetadataTrait for Artist { "hm://metadata/3/artist" } - fn parse(msg: &Self::Message, session: &Session) -> Self { + fn parse(msg: &Self::Message, _: &Session) -> Self { Artist { id: SpotifyId::from_raw(msg.get_gid()), name: msg.get_name().to_owned(), diff --git a/src/session.rs b/src/session.rs index 27275cef..94cdb7dd 100644 --- a/src/session.rs +++ b/src/session.rs @@ -14,7 +14,7 @@ use util::{SpotifyId, FileId, mkdir_existing}; use mercury::{MercuryManager, MercuryRequest, MercuryResponse}; use metadata::{MetadataManager, MetadataRef, MetadataTrait}; use stream::{StreamManager, StreamEvent}; -use audio_key::{AudioKeyManager, AudioKey}; +use audio_key::{AudioKeyManager, AudioKey, AudioKeyError}; use audio_file::{AudioFileManager, AudioFile}; use connection::PacketHandler; @@ -189,7 +189,7 @@ impl Session { self.0.tx_connection.lock().unwrap().send_packet(cmd, data) } - pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future { + pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future { self.0.audio_key.lock().unwrap().request(self, track, file) }