[AudioKeyManager] Convert to async

This commit is contained in:
ashthespy 2021-01-23 22:21:42 +00:00
parent 94fc0a12da
commit c273d51a1d
2 changed files with 16 additions and 26 deletions

View file

@ -14,6 +14,7 @@ version = "0.1.3"
[dependencies]
base64 = "0.13"
thiserror = "1.0"
byteorder = "1.3"
bytes = "0.5"
error-chain = { version = "0.12", default_features = false }

View file

@ -1,13 +1,9 @@
use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use bytes::Bytes;
use futures::channel::oneshot;
use std::collections::HashMap;
use std::io::Write;
use futures::{channel::oneshot, Future};
use std::{
pin::Pin,
task::{Context, Poll},
};
use thiserror::Error;
use crate::spotify_id::{FileId, SpotifyId};
use crate::util::SeqGenerator;
@ -15,8 +11,13 @@ use crate::util::SeqGenerator;
#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)]
pub struct AudioKey(pub [u8; 16]);
#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)]
pub struct AudioKeyError;
#[derive(Error, Debug)]
pub enum AudioKeyError {
#[error("AudioKey sender disconnected")]
Cancelled(#[from] oneshot::Canceled),
#[error("Unknown server response: `{0:?}`")]
UnknownResponse(Vec<u8>),
}
component! {
AudioKeyManager : AudioKeyManagerInner {
@ -44,14 +45,16 @@ impl AudioKeyManager {
data.as_ref()[0],
data.as_ref()[1]
);
let _ = sender.send(Err(AudioKeyError));
let _ = sender.send(Err(AudioKeyError::UnknownResponse(
data.as_ref()[..1].to_vec(),
)));
}
_ => (),
_ => warn!("Unexpected audioKey response: 0x{:x?} {:?}", cmd, data),
}
}
}
pub fn request(&self, track: SpotifyId, file: FileId) -> AudioKeyFuture<AudioKey> {
pub async fn request(&self, track: SpotifyId, file: FileId) -> Result<AudioKey, AudioKeyError> {
let (tx, rx) = oneshot::channel();
let seq = self.lock(move |inner| {
@ -61,7 +64,7 @@ impl AudioKeyManager {
});
self.send_key_request(seq, track, file);
AudioKeyFuture(rx)
rx.await?
}
fn send_key_request(&self, seq: u32, track: SpotifyId, file: FileId) {
@ -74,17 +77,3 @@ impl AudioKeyManager {
self.session().send_packet(0xc, data)
}
}
pub struct AudioKeyFuture<T>(oneshot::Receiver<Result<T, AudioKeyError>>);
impl<T> Future for AudioKeyFuture<T> {
type Output = Result<T, AudioKeyError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
match self.0.poll() {
Poll::Ready(Ok(Ok(value))) => Poll::Ready(Ok(value)),
Poll::Ready(Ok(Err(err))) => Err(err),
Poll::Pending => Poll::Pending,
Err(oneshot::Canceled) => Err(AudioKeyError),
}
}
}