1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-03 01:39:28 +02:00

Update protobuf and related crates to 3.x (#1092)

This commit is contained in:
Lukáš Tyrychtr 2023-01-17 21:46:14 +01:00 committed by GitHub
parent 8941495b80
commit 3662302196
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 694 additions and 672 deletions

View file

@ -13,7 +13,7 @@ async-trait = "0.1"
byteorder = "1"
bytes = "1"
log = "0.4"
protobuf = "2"
protobuf = "3"
thiserror = "1"
uuid = { version = "1", default-features = false }
serde = { version = "1.0", features = ["derive"] }

View file

@ -21,7 +21,7 @@ use crate::{
use librespot_core::{date::Date, Error, Session, SpotifyId};
use librespot_protocol as protocol;
pub use protocol::metadata::Album_Type as AlbumType;
pub use protocol::metadata::album::Type as AlbumType;
use protocol::metadata::Disc as DiscMessage;
#[derive(Debug, Clone)]
@ -90,26 +90,26 @@ impl TryFrom<&<Self as Metadata>::Message> for Album {
fn try_from(album: &<Self as Metadata>::Message) -> Result<Self, Self::Error> {
Ok(Self {
id: album.try_into()?,
name: album.get_name().to_owned(),
artists: album.get_artist().try_into()?,
album_type: album.get_field_type(),
label: album.get_label().to_owned(),
date: album.get_date().try_into()?,
popularity: album.get_popularity(),
genres: album.get_genre().to_vec(),
covers: album.get_cover_group().into(),
external_ids: album.get_external_id().into(),
discs: album.get_disc().try_into()?,
reviews: album.get_review().to_vec(),
copyrights: album.get_copyright().into(),
restrictions: album.get_restriction().into(),
related: album.get_related().try_into()?,
sale_periods: album.get_sale_period().try_into()?,
cover_group: album.get_cover_group().get_image().into(),
original_title: album.get_original_title().to_owned(),
version_title: album.get_version_title().to_owned(),
type_str: album.get_type_str().to_owned(),
availability: album.get_availability().try_into()?,
name: album.name().to_owned(),
artists: album.artist.as_slice().try_into()?,
album_type: album.type_(),
label: album.label().to_owned(),
date: album.date.get_or_default().try_into()?,
popularity: album.popularity(),
genres: album.genre.to_vec(),
covers: album.cover_group.get_or_default().into(),
external_ids: album.external_id.as_slice().into(),
discs: album.disc.as_slice().try_into()?,
reviews: album.review.to_vec(),
copyrights: album.copyright.as_slice().into(),
restrictions: album.restriction.as_slice().into(),
related: album.related.as_slice().try_into()?,
sale_periods: album.sale_period.as_slice().try_into()?,
cover_group: album.cover_group.image.as_slice().into(),
original_title: album.original_title().to_owned(),
version_title: album.version_title().to_owned(),
type_str: album.type_str().to_owned(),
availability: album.availability.as_slice().try_into()?,
})
}
}
@ -120,9 +120,9 @@ impl TryFrom<&DiscMessage> for Disc {
type Error = librespot_core::Error;
fn try_from(disc: &DiscMessage) -> Result<Self, Self::Error> {
Ok(Self {
number: disc.get_number(),
name: disc.get_name().to_owned(),
tracks: disc.get_track().try_into()?,
number: disc.number(),
name: disc.name().to_owned(),
tracks: disc.track.as_slice().try_into()?,
})
}
}

View file

@ -20,7 +20,7 @@ use crate::{
use librespot_core::{Error, Session, SpotifyId};
use librespot_protocol as protocol;
pub use protocol::metadata::ArtistWithRole_ArtistRole as ArtistRole;
pub use protocol::metadata::artist_with_role::ArtistRole;
use protocol::metadata::ActivityPeriod as ActivityPeriodMessage;
use protocol::metadata::AlbumGroup as AlbumGroupMessage;
@ -187,24 +187,29 @@ impl TryFrom<&<Self as Metadata>::Message> for Artist {
fn try_from(artist: &<Self as Metadata>::Message) -> Result<Self, Self::Error> {
Ok(Self {
id: artist.try_into()?,
name: artist.get_name().to_owned(),
popularity: artist.get_popularity(),
top_tracks: artist.get_top_track().try_into()?,
albums: artist.get_album_group().try_into()?,
singles: artist.get_single_group().try_into()?,
compilations: artist.get_compilation_group().try_into()?,
appears_on_albums: artist.get_appears_on_group().try_into()?,
genre: artist.get_genre().to_vec(),
external_ids: artist.get_external_id().into(),
portraits: artist.get_portrait().into(),
biographies: artist.get_biography().into(),
activity_periods: artist.get_activity_period().try_into()?,
restrictions: artist.get_restriction().into(),
related: artist.get_related().try_into()?,
is_portrait_album_cover: artist.get_is_portrait_album_cover(),
portrait_group: artist.get_portrait_group().get_image().into(),
sales_periods: artist.get_sale_period().try_into()?,
availabilities: artist.get_availability().try_into()?,
name: artist.name().to_owned(),
popularity: artist.popularity(),
top_tracks: artist.top_track.as_slice().try_into()?,
albums: artist.album_group.as_slice().try_into()?,
singles: artist.single_group.as_slice().try_into()?,
compilations: artist.compilation_group.as_slice().try_into()?,
appears_on_albums: artist.appears_on_group.as_slice().try_into()?,
genre: artist.genre.to_vec(),
external_ids: artist.external_id.as_slice().into(),
portraits: artist.portrait.as_slice().into(),
biographies: artist.biography.as_slice().into(),
activity_periods: artist.activity_period.as_slice().try_into()?,
restrictions: artist.restriction.as_slice().into(),
related: artist.related.as_slice().try_into()?,
is_portrait_album_cover: artist.is_portrait_album_cover(),
portrait_group: artist
.portrait_group
.get_or_default()
.image
.as_slice()
.into(),
sales_periods: artist.sale_period.as_slice().try_into()?,
availabilities: artist.availability.as_slice().try_into()?,
})
}
}
@ -216,8 +221,8 @@ impl TryFrom<&ArtistWithRoleMessage> for ArtistWithRole {
fn try_from(artist_with_role: &ArtistWithRoleMessage) -> Result<Self, Self::Error> {
Ok(Self {
id: artist_with_role.try_into()?,
name: artist_with_role.get_artist_name().to_owned(),
role: artist_with_role.get_role(),
name: artist_with_role.artist_name().to_owned(),
role: artist_with_role.role(),
})
}
}
@ -228,8 +233,8 @@ impl TryFrom<&TopTracksMessage> for TopTracks {
type Error = librespot_core::Error;
fn try_from(top_tracks: &TopTracksMessage) -> Result<Self, Self::Error> {
Ok(Self {
country: top_tracks.get_country().to_owned(),
tracks: top_tracks.get_track().try_into()?,
country: top_tracks.country().to_owned(),
tracks: top_tracks.track.as_slice().try_into()?,
})
}
}
@ -239,7 +244,7 @@ impl_try_from_repeated!(TopTracksMessage, CountryTopTracks);
impl TryFrom<&AlbumGroupMessage> for AlbumGroup {
type Error = librespot_core::Error;
fn try_from(album_groups: &AlbumGroupMessage) -> Result<Self, Self::Error> {
Ok(Self(album_groups.get_album().try_into()?))
Ok(Self(album_groups.album.as_slice().try_into()?))
}
}
@ -257,14 +262,14 @@ impl_try_from_repeated!(AlbumGroupMessage, AlbumGroups);
impl From<&BiographyMessage> for Biography {
fn from(biography: &BiographyMessage) -> Self {
let portrait_group = biography
.get_portrait_group()
.portrait_group
.iter()
.map(|it| it.get_image().into())
.map(|it| it.image.as_slice().into())
.collect();
Self {
text: biography.get_text().to_owned(),
portraits: biography.get_portrait().into(),
text: biography.text().to_owned(),
portraits: biography.portrait.as_slice().into(),
portrait_group,
}
}
@ -282,11 +287,11 @@ impl TryFrom<&ActivityPeriodMessage> for ActivityPeriod {
period.has_end_year(),
) {
// (decade, start_year, end_year)
(true, false, false) => Self::Decade(period.get_decade().try_into()?),
(true, false, false) => Self::Decade(period.decade().try_into()?),
(false, true, closed_period) => Self::Timespan {
start_year: period.get_start_year().try_into()?,
start_year: period.start_year().try_into()?,
end_year: closed_period
.then(|| period.get_end_year().try_into())
.then(|| period.end_year().try_into())
.transpose()?,
},
_ => {

View file

@ -7,8 +7,8 @@ use std::{
use librespot_core::FileId;
use librespot_protocol as protocol;
pub use protocol::metadata::audio_file::Format as AudioFileFormat;
use protocol::metadata::AudioFile as AudioFileMessage;
pub use protocol::metadata::AudioFile_Format as AudioFileFormat;
use crate::util::impl_deref_wrapped;
@ -45,12 +45,12 @@ impl AudioFiles {
impl From<&[AudioFileMessage]> for AudioFiles {
fn from(files: &[AudioFileMessage]) -> Self {
let audio_files = files
let audio_files: HashMap<AudioFileFormat, FileId> = files
.iter()
.filter_map(|file| {
let file_id = FileId::from(file.get_file_id());
let file_id = FileId::from(file.file_id());
if file.has_format() {
Some((file.get_format(), file_id))
Some((file.format(), file_id))
} else {
trace!("Ignoring file <{}> with unspecified format", file_id);
None

View file

@ -1,5 +1,5 @@
use std::{
convert::{TryFrom, TryInto},
convert::TryFrom,
fmt::Debug,
ops::{Deref, DerefMut},
};
@ -42,8 +42,8 @@ impl TryFrom<&AvailabilityMessage> for Availability {
type Error = librespot_core::Error;
fn try_from(availability: &AvailabilityMessage) -> Result<Self, Self::Error> {
Ok(Self {
catalogue_strs: availability.get_catalogue_str().to_vec(),
start: availability.get_start().try_into()?,
catalogue_strs: availability.catalogue_str.to_vec(),
start: availability.start.get_or_default().try_into()?,
})
}
}

View file

@ -22,8 +22,8 @@ impl_deref_wrapped!(ContentRatings, Vec<ContentRating>);
impl From<&ContentRatingMessage> for ContentRating {
fn from(content_rating: &ContentRatingMessage) -> Self {
Self {
country: content_rating.get_country().to_owned(),
tags: content_rating.get_tag().to_vec(),
country: content_rating.country().to_owned(),
tags: content_rating.tag.to_vec(),
}
}
}

View file

@ -6,8 +6,8 @@ use std::{
use crate::util::{impl_deref_wrapped, impl_from_repeated};
use librespot_protocol as protocol;
pub use protocol::metadata::copyright::Type as CopyrightType;
use protocol::metadata::Copyright as CopyrightMessage;
pub use protocol::metadata::Copyright_Type as CopyrightType;
#[derive(Debug, Clone)]
pub struct Copyright {
@ -23,8 +23,8 @@ impl_deref_wrapped!(Copyrights, Vec<Copyright>);
impl From<&CopyrightMessage> for Copyright {
fn from(copyright: &CopyrightMessage) -> Self {
Self {
copyright_type: copyright.get_field_type(),
text: copyright.get_text().to_owned(),
copyright_type: copyright.type_(),
text: copyright.text().to_owned(),
}
}
}

View file

@ -19,7 +19,7 @@ use crate::{
use librespot_core::{date::Date, Error, Session, SpotifyId};
use librespot_protocol as protocol;
pub use protocol::metadata::Episode_EpisodeType as EpisodeType;
pub use protocol::metadata::episode::EpisodeType;
#[derive(Debug, Clone)]
pub struct Episode {
@ -72,29 +72,29 @@ impl TryFrom<&<Self as Metadata>::Message> for Episode {
fn try_from(episode: &<Self as Metadata>::Message) -> Result<Self, Self::Error> {
Ok(Self {
id: episode.try_into()?,
name: episode.get_name().to_owned(),
duration: episode.get_duration().to_owned(),
audio: episode.get_audio().into(),
description: episode.get_description().to_owned(),
number: episode.get_number(),
publish_time: episode.get_publish_time().try_into()?,
covers: episode.get_cover_image().get_image().into(),
language: episode.get_language().to_owned(),
is_explicit: episode.get_explicit().to_owned(),
show_name: episode.get_show().get_name().to_owned(),
videos: episode.get_video().into(),
video_previews: episode.get_video_preview().into(),
audio_previews: episode.get_audio_preview().into(),
restrictions: episode.get_restriction().into(),
freeze_frames: episode.get_freeze_frame().get_image().into(),
keywords: episode.get_keyword().to_vec(),
allow_background_playback: episode.get_allow_background_playback(),
availability: episode.get_availability().try_into()?,
external_url: episode.get_external_url().to_owned(),
episode_type: episode.get_field_type(),
has_music_and_talk: episode.get_music_and_talk(),
content_rating: episode.get_content_rating().into(),
is_audiobook_chapter: episode.get_is_audiobook_chapter(),
name: episode.name().to_owned(),
duration: episode.duration().to_owned(),
audio: episode.audio.as_slice().into(),
description: episode.description().to_owned(),
number: episode.number(),
publish_time: episode.publish_time.get_or_default().try_into()?,
covers: episode.cover_image.image.as_slice().into(),
language: episode.language().to_owned(),
is_explicit: episode.explicit().to_owned(),
show_name: episode.show.name().to_owned(),
videos: episode.video.as_slice().into(),
video_previews: episode.video_preview.as_slice().into(),
audio_previews: episode.audio_preview.as_slice().into(),
restrictions: episode.restriction.as_slice().into(),
freeze_frames: episode.freeze_frame.image.as_slice().into(),
keywords: episode.keyword.to_vec(),
allow_background_playback: episode.allow_background_playback(),
availability: episode.availability.as_slice().try_into()?,
external_url: episode.external_url().to_owned(),
episode_type: episode.type_(),
has_music_and_talk: episode.music_and_talk(),
content_rating: episode.content_rating.as_slice().into(),
is_audiobook_chapter: episode.is_audiobook_chapter(),
})
}
}

View file

@ -22,8 +22,8 @@ impl_deref_wrapped!(ExternalIds, Vec<ExternalId>);
impl From<&ExternalIdMessage> for ExternalId {
fn from(external_id: &ExternalIdMessage) -> Self {
Self {
external_type: external_id.get_field_type().to_owned(),
id: external_id.get_id().to_owned(),
external_type: external_id.type_().to_owned(),
id: external_id.id().to_owned(),
}
}
}

View file

@ -9,9 +9,9 @@ use crate::util::{impl_deref_wrapped, impl_from_repeated, impl_try_from_repeated
use librespot_core::{FileId, SpotifyId};
use librespot_protocol as protocol;
pub use protocol::metadata::image::Size as ImageSize;
use protocol::metadata::Image as ImageMessage;
use protocol::metadata::ImageGroup;
pub use protocol::metadata::Image_Size as ImageSize;
use protocol::playlist4_external::PictureSize as PictureSizeMessage;
use protocol::playlist_annotate3::TranscodedPicture as TranscodedPictureMessage;
@ -60,9 +60,9 @@ impl From<&ImageMessage> for Image {
fn from(image: &ImageMessage) -> Self {
Self {
id: image.into(),
size: image.get_size(),
width: image.get_width(),
height: image.get_height(),
size: image.size(),
width: image.width(),
height: image.height(),
}
}
}
@ -72,8 +72,8 @@ impl_from_repeated!(ImageMessage, Images);
impl From<&PictureSizeMessage> for PictureSize {
fn from(size: &PictureSizeMessage) -> Self {
Self {
target_name: size.get_target_name().to_owned(),
url: size.get_url().to_owned(),
target_name: size.target_name().to_owned(),
url: size.url().to_owned(),
}
}
}
@ -84,7 +84,7 @@ impl TryFrom<&TranscodedPictureMessage> for TranscodedPicture {
type Error = librespot_core::Error;
fn try_from(picture: &TranscodedPictureMessage) -> Result<Self, Self::Error> {
Ok(Self {
target_name: picture.get_target_name().to_owned(),
target_name: picture.target_name().to_owned(),
uri: picture.try_into()?,
})
}

View file

@ -41,7 +41,7 @@ pub use track::Track;
#[async_trait]
pub trait Metadata: Send + Sized + 'static {
type Message: protobuf::Message;
type Message: protobuf::Message + std::fmt::Debug;
// Request a protobuf
async fn request(session: &Session, id: &SpotifyId) -> RequestResult;

View file

@ -1,4 +1,4 @@
use std::convert::{TryFrom, TryInto};
use std::convert::TryFrom;
use std::fmt::Debug;
use protobuf::Message;
@ -34,11 +34,11 @@ impl Metadata for PlaylistAnnotation {
fn parse(msg: &Self::Message, _: &SpotifyId) -> Result<Self, Error> {
Ok(Self {
description: msg.get_description().to_owned(),
picture: msg.get_picture().to_owned(), // TODO: is this a URL or Spotify URI?
transcoded_pictures: msg.get_transcoded_picture().try_into()?,
has_abuse_reporting: msg.get_is_abuse_reporting_enabled(),
abuse_report_state: msg.get_abuse_report_state(),
description: msg.description().to_owned(),
picture: msg.picture().to_owned(), // TODO: is this a URL or Spotify URI?
transcoded_pictures: msg.transcoded_picture.as_slice().try_into()?,
has_abuse_reporting: msg.is_abuse_reporting_enabled(),
abuse_report_state: msg.abuse_report_state(),
})
}
}
@ -77,11 +77,11 @@ impl TryFrom<&<PlaylistAnnotation as Metadata>::Message> for PlaylistAnnotation
annotation: &<PlaylistAnnotation as Metadata>::Message,
) -> Result<Self, Self::Error> {
Ok(Self {
description: annotation.get_description().to_owned(),
picture: annotation.get_picture().to_owned(),
transcoded_pictures: annotation.get_transcoded_picture().try_into()?,
has_abuse_reporting: annotation.get_is_abuse_reporting_enabled(),
abuse_report_state: annotation.get_abuse_report_state(),
description: annotation.description().to_owned(),
picture: annotation.picture().to_owned(),
transcoded_pictures: annotation.transcoded_picture.as_slice().try_into()?,
has_abuse_reporting: annotation.is_abuse_reporting_enabled(),
abuse_report_state: annotation.abuse_report_state(),
})
}
}

View file

@ -1,6 +1,6 @@
use std::{
collections::HashMap,
convert::{TryFrom, TryInto},
convert::TryFrom,
fmt::Debug,
ops::{Deref, DerefMut},
};
@ -99,16 +99,16 @@ impl TryFrom<&PlaylistAttributesMessage> for PlaylistAttributes {
type Error = librespot_core::Error;
fn try_from(attributes: &PlaylistAttributesMessage) -> Result<Self, Self::Error> {
Ok(Self {
name: attributes.get_name().to_owned(),
description: attributes.get_description().to_owned(),
picture: attributes.get_picture().to_owned(),
is_collaborative: attributes.get_collaborative(),
pl3_version: attributes.get_pl3_version().to_owned(),
is_deleted_by_owner: attributes.get_deleted_by_owner(),
client_id: attributes.get_client_id().to_owned(),
format: attributes.get_format().to_owned(),
format_attributes: attributes.get_format_attributes().into(),
picture_sizes: attributes.get_picture_size().into(),
name: attributes.name().to_owned(),
description: attributes.description().to_owned(),
picture: attributes.picture().to_owned(),
is_collaborative: attributes.collaborative(),
pl3_version: attributes.pl3_version().to_owned(),
is_deleted_by_owner: attributes.deleted_by_owner(),
client_id: attributes.client_id().to_owned(),
format: attributes.format().to_owned(),
format_attributes: attributes.format_attributes.as_slice().into(),
picture_sizes: attributes.picture_size.as_slice().into(),
})
}
}
@ -117,12 +117,7 @@ impl From<&[PlaylistFormatAttributeMessage]> for PlaylistFormatAttribute {
fn from(attributes: &[PlaylistFormatAttributeMessage]) -> Self {
let format_attributes = attributes
.iter()
.map(|attribute| {
(
attribute.get_key().to_owned(),
attribute.get_value().to_owned(),
)
})
.map(|attribute| (attribute.key().to_owned(), attribute.value().to_owned()))
.collect();
PlaylistFormatAttribute(format_attributes)
@ -133,12 +128,12 @@ impl TryFrom<&PlaylistItemAttributesMessage> for PlaylistItemAttributes {
type Error = librespot_core::Error;
fn try_from(attributes: &PlaylistItemAttributesMessage) -> Result<Self, Self::Error> {
Ok(Self {
added_by: attributes.get_added_by().to_owned(),
timestamp: Date::from_timestamp_ms(attributes.get_timestamp())?,
seen_at: Date::from_timestamp_ms(attributes.get_seen_at())?,
is_public: attributes.get_public(),
format_attributes: attributes.get_format_attributes().into(),
item_id: attributes.get_item_id().to_owned(),
added_by: attributes.added_by().to_owned(),
timestamp: Date::from_timestamp_ms(attributes.timestamp())?,
seen_at: Date::from_timestamp_ms(attributes.seen_at())?,
is_public: attributes.public(),
format_attributes: attributes.format_attributes.as_slice().into(),
item_id: attributes.item_id().to_owned(),
})
}
}
@ -146,8 +141,14 @@ impl TryFrom<&PlaylistPartialAttributesMessage> for PlaylistPartialAttributes {
type Error = librespot_core::Error;
fn try_from(attributes: &PlaylistPartialAttributesMessage) -> Result<Self, Self::Error> {
Ok(Self {
values: attributes.get_values().try_into()?,
no_value: attributes.get_no_value().into(),
values: attributes.values.get_or_default().try_into()?,
no_value: attributes
.no_value
.iter()
.map(|v| v.enum_value_or_default())
.collect::<Vec<PlaylistAttributeKind>>()
.as_slice()
.into(),
})
}
}
@ -156,8 +157,14 @@ impl TryFrom<&PlaylistPartialItemAttributesMessage> for PlaylistPartialItemAttri
type Error = librespot_core::Error;
fn try_from(attributes: &PlaylistPartialItemAttributesMessage) -> Result<Self, Self::Error> {
Ok(Self {
values: attributes.get_values().try_into()?,
no_value: attributes.get_no_value().into(),
values: attributes.values.get_or_default().try_into()?,
no_value: attributes
.no_value
.iter()
.map(|v| v.enum_value_or_default())
.collect::<Vec<PlaylistItemAttributeKind>>()
.as_slice()
.into(),
})
}
}
@ -166,8 +173,8 @@ impl TryFrom<&PlaylistUpdateAttributesMessage> for PlaylistUpdateAttributes {
type Error = librespot_core::Error;
fn try_from(update: &PlaylistUpdateAttributesMessage) -> Result<Self, Self::Error> {
Ok(Self {
new_attributes: update.get_new_attributes().try_into()?,
old_attributes: update.get_old_attributes().try_into()?,
new_attributes: update.new_attributes.get_or_default().try_into()?,
old_attributes: update.old_attributes.get_or_default().try_into()?,
})
}
}
@ -176,9 +183,9 @@ impl TryFrom<&PlaylistUpdateItemAttributesMessage> for PlaylistUpdateItemAttribu
type Error = librespot_core::Error;
fn try_from(update: &PlaylistUpdateItemAttributesMessage) -> Result<Self, Self::Error> {
Ok(Self {
index: update.get_index(),
new_attributes: update.get_new_attributes().try_into()?,
old_attributes: update.get_old_attributes().try_into()?,
index: update.index(),
new_attributes: update.new_attributes.get_or_default().try_into()?,
old_attributes: update.old_attributes.get_or_default().try_into()?,
})
}
}

View file

@ -1,7 +1,4 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
};
use std::{convert::TryFrom, fmt::Debug};
use super::operation::PlaylistOperations;
@ -21,9 +18,19 @@ impl TryFrom<&DiffMessage> for PlaylistDiff {
type Error = librespot_core::Error;
fn try_from(diff: &DiffMessage) -> Result<Self, Self::Error> {
Ok(Self {
from_revision: diff.get_from_revision().try_into()?,
operations: diff.get_ops().try_into()?,
to_revision: diff.get_to_revision().try_into()?,
from_revision: diff
.from_revision
.clone()
.unwrap_or_default()
.as_slice()
.try_into()?,
operations: diff.ops.as_slice().try_into()?,
to_revision: diff
.to_revision
.clone()
.unwrap_or_default()
.as_slice()
.try_into()?,
})
}
}

View file

@ -58,7 +58,7 @@ impl TryFrom<&PlaylistItemMessage> for PlaylistItem {
fn try_from(item: &PlaylistItemMessage) -> Result<Self, Self::Error> {
Ok(Self {
id: item.try_into()?,
attributes: item.get_attributes().try_into()?,
attributes: item.attributes.get_or_default().try_into()?,
})
}
}
@ -69,10 +69,10 @@ impl TryFrom<&PlaylistItemsMessage> for PlaylistItemList {
type Error = librespot_core::Error;
fn try_from(list_items: &PlaylistItemsMessage) -> Result<Self, Self::Error> {
Ok(Self {
position: list_items.get_pos(),
is_truncated: list_items.get_truncated(),
items: list_items.get_items().try_into()?,
meta_items: list_items.get_meta_items().try_into()?,
position: list_items.pos(),
is_truncated: list_items.truncated(),
items: list_items.items.as_slice().try_into()?,
meta_items: list_items.meta_items.as_slice().try_into()?,
})
}
}
@ -82,12 +82,12 @@ impl TryFrom<&PlaylistMetaItemMessage> for PlaylistMetaItem {
fn try_from(item: &PlaylistMetaItemMessage) -> Result<Self, Self::Error> {
Ok(Self {
revision: item.try_into()?,
attributes: item.get_attributes().try_into()?,
length: item.get_length(),
timestamp: Date::from_timestamp_ms(item.get_timestamp())?,
owner_username: item.get_owner_username().to_owned(),
has_abuse_reporting: item.get_abuse_reporting_enabled(),
capabilities: item.get_capabilities().into(),
attributes: item.attributes.get_or_default().try_into()?,
length: item.length(),
timestamp: Date::from_timestamp_ms(item.timestamp())?,
owner_username: item.owner_username().to_owned(),
has_abuse_reporting: item.abuse_reporting_enabled(),
capabilities: item.capabilities.get_or_default().into(),
})
}
}

View file

@ -129,7 +129,7 @@ impl Metadata for Playlist {
impl TryFrom<&<Playlist as Metadata>::Message> for SelectedListContent {
type Error = librespot_core::Error;
fn try_from(playlist: &<Playlist as Metadata>::Message) -> Result<Self, Self::Error> {
let timestamp = playlist.get_timestamp();
let timestamp = playlist.timestamp();
let timestamp = if timestamp > 9295169800000 {
// timestamp is way out of range for milliseconds. Some seem to be in microseconds?
// Observed on playlists where:
@ -146,25 +146,37 @@ impl TryFrom<&<Playlist as Metadata>::Message> for SelectedListContent {
let timestamp = Date::from_timestamp_ms(timestamp)?;
Ok(Self {
revision: playlist.get_revision().to_owned(),
length: playlist.get_length(),
attributes: playlist.get_attributes().try_into()?,
contents: playlist.get_contents().try_into()?,
revision: playlist.revision().to_owned(),
length: playlist.length(),
attributes: playlist.attributes.get_or_default().try_into()?,
contents: playlist.contents.get_or_default().try_into()?,
diff: playlist.diff.as_ref().map(TryInto::try_into).transpose()?,
sync_result: playlist
.sync_result
.as_ref()
.map(TryInto::try_into)
.transpose()?,
resulting_revisions: playlist.get_resulting_revisions().try_into()?,
has_multiple_heads: playlist.get_multiple_heads(),
is_up_to_date: playlist.get_up_to_date(),
nonces: playlist.get_nonces().into(),
resulting_revisions: Playlists(
playlist
.resulting_revisions
.iter()
.map(|p| p.try_into())
.collect::<Result<Vec<SpotifyId>, Error>>()?,
),
has_multiple_heads: playlist.multiple_heads(),
is_up_to_date: playlist.up_to_date(),
nonces: playlist.nonces.clone(),
timestamp,
owner_username: playlist.get_owner_username().to_owned(),
has_abuse_reporting: playlist.get_abuse_reporting_enabled(),
capabilities: playlist.get_capabilities().into(),
geoblocks: playlist.get_geoblock().into(),
owner_username: playlist.owner_username().to_owned(),
has_abuse_reporting: playlist.abuse_reporting_enabled(),
capabilities: playlist.capabilities.get_or_default().into(),
geoblocks: Geoblocks(
playlist
.geoblock
.iter()
.map(|b| b.enum_value_or_default())
.collect(),
),
})
}
}

View file

@ -1,5 +1,5 @@
use std::{
convert::{TryFrom, TryInto},
convert::TryFrom,
fmt::Debug,
ops::{Deref, DerefMut},
};
@ -13,10 +13,10 @@ use crate::{
};
use librespot_protocol as protocol;
pub use protocol::playlist4_external::op::Kind as PlaylistOperationKind;
use protocol::playlist4_external::Add as PlaylistAddMessage;
use protocol::playlist4_external::Mov as PlaylistMoveMessage;
use protocol::playlist4_external::Op as PlaylistOperationMessage;
pub use protocol::playlist4_external::Op_Kind as PlaylistOperationKind;
use protocol::playlist4_external::Rem as PlaylistRemoveMessage;
#[derive(Debug, Clone)]
@ -61,12 +61,18 @@ impl TryFrom<&PlaylistOperationMessage> for PlaylistOperation {
type Error = librespot_core::Error;
fn try_from(operation: &PlaylistOperationMessage) -> Result<Self, Self::Error> {
Ok(Self {
kind: operation.get_kind(),
add: operation.get_add().try_into()?,
rem: operation.get_rem().try_into()?,
mov: operation.get_mov().into(),
update_item_attributes: operation.get_update_item_attributes().try_into()?,
update_list_attributes: operation.get_update_list_attributes().try_into()?,
kind: operation.kind(),
add: operation.add.get_or_default().try_into()?,
rem: operation.rem.get_or_default().try_into()?,
mov: operation.mov.get_or_default().into(),
update_item_attributes: operation
.update_item_attributes
.get_or_default()
.try_into()?,
update_list_attributes: operation
.update_list_attributes
.get_or_default()
.try_into()?,
})
}
}
@ -77,10 +83,10 @@ impl TryFrom<&PlaylistAddMessage> for PlaylistOperationAdd {
type Error = librespot_core::Error;
fn try_from(add: &PlaylistAddMessage) -> Result<Self, Self::Error> {
Ok(Self {
from_index: add.get_from_index(),
items: add.get_items().try_into()?,
add_last: add.get_add_last(),
add_first: add.get_add_first(),
from_index: add.from_index(),
items: add.items.as_slice().try_into()?,
add_last: add.add_last(),
add_first: add.add_first(),
})
}
}
@ -88,9 +94,9 @@ impl TryFrom<&PlaylistAddMessage> for PlaylistOperationAdd {
impl From<&PlaylistMoveMessage> for PlaylistOperationMove {
fn from(mov: &PlaylistMoveMessage) -> Self {
Self {
from_index: mov.get_from_index(),
length: mov.get_length(),
to_index: mov.get_to_index(),
from_index: mov.from_index(),
length: mov.length(),
to_index: mov.to_index(),
}
}
}
@ -99,10 +105,10 @@ impl TryFrom<&PlaylistRemoveMessage> for PlaylistOperationRemove {
type Error = librespot_core::Error;
fn try_from(remove: &PlaylistRemoveMessage) -> Result<Self, Self::Error> {
Ok(Self {
from_index: remove.get_from_index(),
length: remove.get_length(),
items: remove.get_items().try_into()?,
has_items_as_key: remove.get_items_as_key(),
from_index: remove.from_index(),
length: remove.length(),
items: remove.items.as_slice().try_into()?,
has_items_as_key: remove.items_as_key(),
})
}
}

View file

@ -27,12 +27,18 @@ impl_deref_wrapped!(PermissionLevels, Vec<PermissionLevel>);
impl From<&CapabilitiesMessage> for Capabilities {
fn from(playlist: &CapabilitiesMessage) -> Self {
Self {
can_view: playlist.get_can_view(),
can_administrate_permissions: playlist.get_can_administrate_permissions(),
grantable_levels: playlist.get_grantable_level().into(),
can_edit_metadata: playlist.get_can_edit_metadata(),
can_edit_items: playlist.get_can_edit_items(),
can_cancel_membership: playlist.get_can_cancel_membership(),
can_view: playlist.can_view(),
can_administrate_permissions: playlist.can_administrate_permissions(),
grantable_levels: PermissionLevels(
playlist
.grantable_level
.iter()
.map(|l| l.enum_value_or_default())
.collect(),
),
can_edit_metadata: playlist.can_edit_metadata(),
can_edit_items: playlist.can_edit_items(),
can_cancel_membership: playlist.can_cancel_membership(),
}
}
}

View file

@ -9,8 +9,8 @@ use crate::util::{impl_from_repeated, impl_from_repeated_copy};
use protocol::metadata::Restriction as RestrictionMessage;
use librespot_protocol as protocol;
pub use protocol::metadata::Restriction_Catalogue as RestrictionCatalogue;
pub use protocol::metadata::Restriction_Type as RestrictionType;
pub use protocol::metadata::restriction::Catalogue as RestrictionCatalogue;
pub use protocol::metadata::restriction::Type as RestrictionType;
#[derive(Debug, Clone)]
pub struct Restriction {
@ -43,25 +43,30 @@ impl Restriction {
impl From<&RestrictionMessage> for Restriction {
fn from(restriction: &RestrictionMessage) -> Self {
let countries_allowed = if restriction.has_countries_allowed() {
Some(Self::parse_country_codes(
restriction.get_countries_allowed(),
))
Some(Self::parse_country_codes(restriction.countries_allowed()))
} else {
None
};
let countries_forbidden = if restriction.has_countries_forbidden() {
Some(Self::parse_country_codes(
restriction.get_countries_forbidden(),
))
Some(Self::parse_country_codes(restriction.countries_forbidden()))
} else {
None
};
Self {
catalogues: restriction.get_catalogue().into(),
restriction_type: restriction.get_field_type(),
catalogue_strs: restriction.get_catalogue_str().to_vec(),
catalogues: restriction
.catalogue
.iter()
.map(|c| c.enum_value_or_default())
.collect::<Vec<RestrictionCatalogue>>()
.as_slice()
.into(),
restriction_type: restriction
.type_
.unwrap_or_default()
.enum_value_or_default(),
catalogue_strs: restriction.catalogue_str.to_vec(),
countries_allowed,
countries_forbidden,
}

View file

@ -1,5 +1,5 @@
use std::{
convert::{TryFrom, TryInto},
convert::TryFrom,
fmt::Debug,
ops::{Deref, DerefMut},
};
@ -30,9 +30,9 @@ impl TryFrom<&SalePeriodMessage> for SalePeriod {
type Error = librespot_core::Error;
fn try_from(sale_period: &SalePeriodMessage) -> Result<Self, Self::Error> {
Ok(Self {
restrictions: sale_period.get_restriction().into(),
start: sale_period.get_start().try_into()?,
end: sale_period.get_end().try_into()?,
restrictions: sale_period.restriction.as_slice().into(),
start: sale_period.start.get_or_default().try_into()?,
end: sale_period.end.get_or_default().try_into()?,
})
}
}

View file

@ -11,8 +11,8 @@ use crate::{
use librespot_core::{Error, Session, SpotifyId};
use librespot_protocol as protocol;
pub use protocol::metadata::Show_ConsumptionOrder as ShowConsumptionOrder;
pub use protocol::metadata::Show_MediaType as ShowMediaType;
pub use protocol::metadata::show::ConsumptionOrder as ShowConsumptionOrder;
pub use protocol::metadata::show::MediaType as ShowMediaType;
#[derive(Debug, Clone)]
pub struct Show {
@ -53,22 +53,22 @@ impl TryFrom<&<Self as Metadata>::Message> for Show {
fn try_from(show: &<Self as Metadata>::Message) -> Result<Self, Self::Error> {
Ok(Self {
id: show.try_into()?,
name: show.get_name().to_owned(),
description: show.get_description().to_owned(),
publisher: show.get_publisher().to_owned(),
language: show.get_language().to_owned(),
is_explicit: show.get_explicit(),
covers: show.get_cover_image().get_image().into(),
episodes: show.get_episode().try_into()?,
copyrights: show.get_copyright().into(),
restrictions: show.get_restriction().into(),
keywords: show.get_keyword().to_vec(),
media_type: show.get_media_type(),
consumption_order: show.get_consumption_order(),
availability: show.get_availability().try_into()?,
trailer_uri: SpotifyId::from_uri(show.get_trailer_uri())?,
has_music_and_talk: show.get_music_and_talk(),
is_audiobook: show.get_is_audiobook(),
name: show.name().to_owned(),
description: show.description().to_owned(),
publisher: show.publisher().to_owned(),
language: show.language().to_owned(),
is_explicit: show.explicit(),
covers: show.cover_image.image.as_slice().into(),
episodes: show.episode.as_slice().try_into()?,
copyrights: show.copyright.as_slice().into(),
restrictions: show.restriction.as_slice().into(),
keywords: show.keyword.to_vec(),
media_type: show.media_type(),
consumption_order: show.consumption_order(),
availability: show.availability.as_slice().try_into()?,
trailer_uri: SpotifyId::from_uri(show.trailer_uri())?,
has_music_and_talk: show.music_and_talk(),
is_audiobook: show.is_audiobook(),
})
}
}

View file

@ -73,31 +73,30 @@ impl TryFrom<&<Self as Metadata>::Message> for Track {
fn try_from(track: &<Self as Metadata>::Message) -> Result<Self, Self::Error> {
Ok(Self {
id: track.try_into()?,
name: track.get_name().to_owned(),
album: track.get_album().try_into()?,
artists: track.get_artist().try_into()?,
number: track.get_number(),
disc_number: track.get_disc_number(),
duration: track.get_duration(),
popularity: track.get_popularity(),
is_explicit: track.get_explicit(),
external_ids: track.get_external_id().into(),
restrictions: track.get_restriction().into(),
files: track.get_file().into(),
alternatives: track.get_alternative().try_into()?,
sale_periods: track.get_sale_period().try_into()?,
previews: track.get_preview().into(),
tags: track.get_tags().to_vec(),
earliest_live_timestamp: Date::from_timestamp_ms(track.get_earliest_live_timestamp())?,
has_lyrics: track.get_has_lyrics(),
availability: track.get_availability().try_into()?,
licensor: Uuid::from_slice(track.get_licensor().get_uuid())
.unwrap_or_else(|_| Uuid::nil()),
language_of_performance: track.get_language_of_performance().to_vec(),
content_ratings: track.get_content_rating().into(),
original_title: track.get_original_title().to_owned(),
version_title: track.get_version_title().to_owned(),
artists_with_role: track.get_artist_with_role().try_into()?,
name: track.name().to_owned(),
album: track.album.get_or_default().try_into()?,
artists: track.artist.as_slice().try_into()?,
number: track.number(),
disc_number: track.disc_number(),
duration: track.duration(),
popularity: track.popularity(),
is_explicit: track.explicit(),
external_ids: track.external_id.as_slice().into(),
restrictions: track.restriction.as_slice().into(),
files: track.file.as_slice().into(),
alternatives: track.alternative.as_slice().try_into()?,
sale_periods: track.sale_period.as_slice().try_into()?,
previews: track.preview.as_slice().into(),
tags: track.tags.to_vec(),
earliest_live_timestamp: Date::from_timestamp_ms(track.earliest_live_timestamp())?,
has_lyrics: track.has_lyrics(),
availability: track.availability.as_slice().try_into()?,
licensor: Uuid::from_slice(track.licensor.uuid()).unwrap_or_else(|_| Uuid::nil()),
language_of_performance: track.language_of_performance.to_vec(),
content_ratings: track.content_rating.as_slice().into(),
original_title: track.original_title().to_owned(),
version_title: track.version_title().to_owned(),
artists_with_role: track.artist_with_role.as_slice().try_into()?,
})
}
}