Migrated metadata crate to futures 0.3

This commit is contained in:
johannesd3 2021-01-21 22:07:16 +01:00
parent 6867ad0750
commit 424ba3ae25
2 changed files with 45 additions and 55 deletions

View file

@ -8,8 +8,9 @@ repository = "https://github.com/librespot-org/librespot"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
async-trait = "0.1"
byteorder = "1.3" byteorder = "1.3"
futures = "0.1" futures = "0.3"
linear-map = "1.2" linear-map = "1.2"
protobuf = "~2.14.0" protobuf = "~2.14.0"
log = "0.4" log = "0.4"

View file

@ -1,6 +1,11 @@
#![allow(clippy::unused_io_amount)]
#![allow(clippy::redundant_field_names)]
#[macro_use] #[macro_use]
extern crate log; extern crate log;
#[macro_use]
extern crate async_trait;
extern crate byteorder; extern crate byteorder;
extern crate futures; extern crate futures;
extern crate linear_map; extern crate linear_map;
@ -11,8 +16,6 @@ extern crate librespot_protocol as protocol;
pub mod cover; pub mod cover;
use futures::future;
use futures::Future;
use linear_map::LinearMap; use linear_map::LinearMap;
use librespot_core::mercury::MercuryError; use librespot_core::mercury::MercuryError;
@ -69,81 +72,67 @@ pub struct AudioItem {
} }
impl AudioItem { impl AudioItem {
pub fn get_audio_item( pub async fn get_audio_item(session: &Session, id: SpotifyId) -> Result<Self, MercuryError> {
session: &Session,
id: SpotifyId,
) -> Box<dyn Future<Item = AudioItem, Error = MercuryError>> {
match id.audio_type { match id.audio_type {
SpotifyAudioType::Track => Track::get_audio_item(session, id), SpotifyAudioType::Track => Track::get_audio_item(session, id).await,
SpotifyAudioType::Podcast => Episode::get_audio_item(session, id), SpotifyAudioType::Podcast => Episode::get_audio_item(session, id).await,
SpotifyAudioType::NonPlayable => { SpotifyAudioType::NonPlayable => Err(MercuryError),
Box::new(future::err::<AudioItem, MercuryError>(MercuryError))
}
} }
} }
} }
#[async_trait]
trait AudioFiles { trait AudioFiles {
fn get_audio_item( async fn get_audio_item(session: &Session, id: SpotifyId) -> Result<AudioItem, MercuryError>;
session: &Session,
id: SpotifyId,
) -> Box<dyn Future<Item = AudioItem, Error = MercuryError>>;
} }
#[async_trait]
impl AudioFiles for Track { impl AudioFiles for Track {
fn get_audio_item( async fn get_audio_item(session: &Session, id: SpotifyId) -> Result<AudioItem, MercuryError> {
session: &Session, let item = Self::get(session, id).await?;
id: SpotifyId, Ok(AudioItem {
) -> Box<dyn Future<Item = AudioItem, Error = MercuryError>> { id: id,
Box::new(Self::get(session, id).and_then(move |item| { uri: format!("spotify:track:{}", id.to_base62()),
Ok(AudioItem { files: item.files,
id: id, name: item.name,
uri: format!("spotify:track:{}", id.to_base62()), duration: item.duration,
files: item.files, available: item.available,
name: item.name, alternatives: Some(item.alternatives),
duration: item.duration, })
available: item.available,
alternatives: Some(item.alternatives),
})
}))
} }
} }
#[async_trait]
impl AudioFiles for Episode { impl AudioFiles for Episode {
fn get_audio_item( async fn get_audio_item(session: &Session, id: SpotifyId) -> Result<AudioItem, MercuryError> {
session: &Session, let item = Self::get(session, id).await?;
id: SpotifyId,
) -> Box<dyn Future<Item = AudioItem, Error = MercuryError>> { Ok(AudioItem {
Box::new(Self::get(session, id).and_then(move |item| { id: id,
Ok(AudioItem { uri: format!("spotify:episode:{}", id.to_base62()),
id: id, files: item.files,
uri: format!("spotify:episode:{}", id.to_base62()), name: item.name,
files: item.files, duration: item.duration,
name: item.name, available: item.available,
duration: item.duration, alternatives: None,
available: item.available, })
alternatives: None,
})
}))
} }
} }
#[async_trait]
pub trait Metadata: Send + Sized + 'static { pub trait Metadata: Send + Sized + 'static {
type Message: protobuf::Message; type Message: protobuf::Message;
fn request_url(id: SpotifyId) -> String; fn request_url(id: SpotifyId) -> String;
fn parse(msg: &Self::Message, session: &Session) -> Self; fn parse(msg: &Self::Message, session: &Session) -> Self;
fn get(session: &Session, id: SpotifyId) -> Box<dyn Future<Item = Self, Error = MercuryError>> { async fn get(session: &Session, id: SpotifyId) -> Result<Self, MercuryError> {
let uri = Self::request_url(id); let uri = Self::request_url(id);
let request = session.mercury().get(uri); let response = session.mercury().get(uri).await?;
let data = response.payload.first().expect("Empty payload");
let msg: Self::Message = protobuf::parse_from_bytes(data).unwrap();
let session = session.clone(); Ok(Self::parse(&msg, &session))
Box::new(request.and_then(move |response| {
let data = response.payload.first().expect("Empty payload");
let msg: Self::Message = protobuf::parse_from_bytes(data).unwrap();
Ok(Self::parse(&msg, &session))
}))
} }
} }