Implement DerefMut for wrapper types in metadata

- Change the `Deref` implementations for metadata wrapper types to use a
  new `impl_deref_wrapped` macro
- The macro implements `Deref` and `DerefMut`
This commit is contained in:
Daniel M 2022-08-02 12:45:37 +02:00
parent e5092c84fd
commit a7fa0e2299
19 changed files with 127 additions and 234 deletions

View file

@ -1,13 +1,21 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use crate::{
artist::Artists, availability::Availabilities, copyright::Copyrights, external_id::ExternalIds,
image::Images, request::RequestResult, restriction::Restrictions, sale_period::SalePeriods,
track::Tracks, util::try_from_repeated_message, Metadata,
artist::Artists,
availability::Availabilities,
copyright::Copyrights,
external_id::ExternalIds,
image::Images,
request::RequestResult,
restriction::Restrictions,
sale_period::SalePeriods,
track::Tracks,
util::{impl_deref_wrapped, try_from_repeated_message},
Metadata,
};
use librespot_core::{date::Date, Error, Session, SpotifyId};
@ -44,12 +52,7 @@ pub struct Album {
#[derive(Debug, Clone, Default)]
pub struct Albums(pub Vec<SpotifyId>);
impl Deref for Albums {
type Target = Vec<SpotifyId>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Albums, Vec<SpotifyId>);
#[derive(Debug, Clone)]
pub struct Disc {
@ -61,12 +64,7 @@ pub struct Disc {
#[derive(Debug, Clone, Default)]
pub struct Discs(pub Vec<Disc>);
impl Deref for Discs {
type Target = Vec<Disc>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Discs, Vec<Disc>);
impl Album {
pub fn tracks(&self) -> Tracks {

View file

@ -1,7 +1,7 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use crate::{
@ -13,7 +13,7 @@ use crate::{
restriction::Restrictions,
sale_period::SalePeriods,
track::Tracks,
util::{from_repeated_message, try_from_repeated_message},
util::{from_repeated_message, impl_deref_wrapped, try_from_repeated_message},
Metadata,
};
@ -54,12 +54,7 @@ pub struct Artist {
#[derive(Debug, Clone, Default)]
pub struct Artists(pub Vec<Artist>);
impl Deref for Artists {
type Target = Vec<Artist>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Artists, Vec<Artist>);
#[derive(Debug, Clone)]
pub struct ArtistWithRole {
@ -71,12 +66,7 @@ pub struct ArtistWithRole {
#[derive(Debug, Clone, Default)]
pub struct ArtistsWithRole(pub Vec<ArtistWithRole>);
impl Deref for ArtistsWithRole {
type Target = Vec<ArtistWithRole>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(ArtistsWithRole, Vec<ArtistWithRole>);
#[derive(Debug, Clone)]
pub struct TopTracks {
@ -87,22 +77,12 @@ pub struct TopTracks {
#[derive(Debug, Clone, Default)]
pub struct CountryTopTracks(pub Vec<TopTracks>);
impl Deref for CountryTopTracks {
type Target = Vec<TopTracks>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(CountryTopTracks, Vec<TopTracks>);
#[derive(Debug, Clone, Default)]
pub struct AlbumGroup(pub Albums);
impl Deref for AlbumGroup {
type Target = Albums;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(AlbumGroup, Albums);
/// `AlbumGroups` contains collections of album variants (different releases of the same album).
/// Ignoring the wrapping types it is structured roughly like this:
@ -116,12 +96,7 @@ impl Deref for AlbumGroup {
#[derive(Debug, Clone, Default)]
pub struct AlbumGroups(pub Vec<AlbumGroup>);
impl Deref for AlbumGroups {
type Target = Vec<AlbumGroup>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(AlbumGroups, Vec<AlbumGroup>);
#[derive(Debug, Clone)]
pub struct Biography {
@ -133,12 +108,7 @@ pub struct Biography {
#[derive(Debug, Clone, Default)]
pub struct Biographies(pub Vec<Biography>);
impl Deref for Biographies {
type Target = Vec<Biography>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Biographies, Vec<Biography>);
#[derive(Debug, Clone)]
pub struct ActivityPeriod {
@ -150,12 +120,7 @@ pub struct ActivityPeriod {
#[derive(Debug, Clone, Default)]
pub struct ActivityPeriods(pub Vec<ActivityPeriod>);
impl Deref for ActivityPeriods {
type Target = Vec<ActivityPeriod>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(ActivityPeriods, Vec<ActivityPeriod>);
impl CountryTopTracks {
pub fn for_country(&self, country: &str) -> Tracks {

View file

@ -1,4 +1,8 @@
use std::{collections::HashMap, fmt::Debug, ops::Deref};
use std::{
collections::HashMap,
fmt::Debug,
ops::{Deref, DerefMut},
};
use librespot_core::FileId;
@ -6,15 +10,12 @@ use librespot_protocol as protocol;
use protocol::metadata::AudioFile as AudioFileMessage;
pub use protocol::metadata::AudioFile_Format as AudioFileFormat;
use crate::util::impl_deref_wrapped;
#[derive(Debug, Clone, Default)]
pub struct AudioFiles(pub HashMap<AudioFileFormat, FileId>);
impl Deref for AudioFiles {
type Target = HashMap<AudioFileFormat, FileId>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(AudioFiles, HashMap<AudioFileFormat, FileId>);
impl AudioFiles {
pub fn is_ogg_vorbis(format: AudioFileFormat) -> bool {

View file

@ -1,12 +1,12 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use thiserror::Error;
use crate::util::try_from_repeated_message;
use crate::util::{impl_deref_wrapped, try_from_repeated_message};
use librespot_core::date::Date;
@ -24,12 +24,7 @@ pub struct Availability {
#[derive(Debug, Clone, Default)]
pub struct Availabilities(pub Vec<Availability>);
impl Deref for Availabilities {
type Target = Vec<Availability>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Availabilities, Vec<Availability>);
#[derive(Debug, Copy, Clone, Error)]
pub enum UnavailabilityReason {

View file

@ -1,6 +1,9 @@
use std::{fmt::Debug, ops::Deref};
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
use crate::util::from_repeated_message;
use crate::util::{from_repeated_message, impl_deref_wrapped};
use librespot_protocol as protocol;
use protocol::metadata::ContentRating as ContentRatingMessage;
@ -14,12 +17,7 @@ pub struct ContentRating {
#[derive(Debug, Clone, Default)]
pub struct ContentRatings(pub Vec<ContentRating>);
impl Deref for ContentRatings {
type Target = Vec<ContentRating>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(ContentRatings, Vec<ContentRating>);
impl From<&ContentRatingMessage> for ContentRating {
fn from(content_rating: &ContentRatingMessage) -> Self {

View file

@ -1,6 +1,9 @@
use std::{fmt::Debug, ops::Deref};
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
use crate::util::from_repeated_message;
use crate::util::{from_repeated_message, impl_deref_wrapped};
use librespot_protocol as protocol;
use protocol::metadata::Copyright as CopyrightMessage;
@ -15,12 +18,7 @@ pub struct Copyright {
#[derive(Debug, Clone, Default)]
pub struct Copyrights(pub Vec<Copyright>);
impl Deref for Copyrights {
type Target = Vec<Copyright>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Copyrights, Vec<Copyright>);
impl From<&CopyrightMessage> for Copyright {
fn from(copyright: &CopyrightMessage) -> Self {

View file

@ -1,7 +1,7 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use crate::{
@ -14,7 +14,7 @@ use crate::{
image::Images,
request::RequestResult,
restriction::Restrictions,
util::try_from_repeated_message,
util::{impl_deref_wrapped, try_from_repeated_message},
video::VideoFiles,
Metadata,
};
@ -55,12 +55,7 @@ pub struct Episode {
#[derive(Debug, Clone, Default)]
pub struct Episodes(pub Vec<SpotifyId>);
impl Deref for Episodes {
type Target = Vec<SpotifyId>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Episodes, Vec<SpotifyId>);
#[async_trait]
impl InnerAudioItem for Episode {

View file

@ -1,6 +1,9 @@
use std::{fmt::Debug, ops::Deref};
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
use crate::util::from_repeated_message;
use crate::util::{from_repeated_message, impl_deref_wrapped};
use librespot_protocol as protocol;
use protocol::metadata::ExternalId as ExternalIdMessage;
@ -14,12 +17,7 @@ pub struct ExternalId {
#[derive(Debug, Clone, Default)]
pub struct ExternalIds(pub Vec<ExternalId>);
impl Deref for ExternalIds {
type Target = Vec<ExternalId>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(ExternalIds, Vec<ExternalId>);
impl From<&ExternalIdMessage> for ExternalId {
fn from(external_id: &ExternalIdMessage) -> Self {

View file

@ -1,10 +1,10 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use crate::util::{from_repeated_message, try_from_repeated_message};
use crate::util::{from_repeated_message, impl_deref_wrapped, try_from_repeated_message};
use librespot_core::{FileId, SpotifyId};
@ -25,12 +25,7 @@ pub struct Image {
#[derive(Debug, Clone, Default)]
pub struct Images(pub Vec<Image>);
impl Deref for Images {
type Target = Vec<Image>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Images, Vec<Image>);
#[derive(Debug, Clone)]
pub struct PictureSize {
@ -41,12 +36,7 @@ pub struct PictureSize {
#[derive(Debug, Clone, Default)]
pub struct PictureSizes(pub Vec<PictureSize>);
impl Deref for PictureSizes {
type Target = Vec<PictureSize>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(PictureSizes, Vec<PictureSize>);
#[derive(Debug, Clone)]
pub struct TranscodedPicture {
@ -57,12 +47,7 @@ pub struct TranscodedPicture {
#[derive(Debug, Clone)]
pub struct TranscodedPictures(pub Vec<TranscodedPicture>);
impl Deref for TranscodedPictures {
type Target = Vec<TranscodedPicture>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(TranscodedPictures, Vec<TranscodedPicture>);
impl From<&ImageMessage> for Image {
fn from(image: &ImageMessage) -> Self {

View file

@ -2,10 +2,13 @@ use std::{
collections::HashMap,
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use crate::{image::PictureSizes, util::from_repeated_enum};
use crate::{
image::PictureSizes,
util::{from_repeated_enum, impl_deref_wrapped},
};
use librespot_core::date::Date;
@ -37,24 +40,14 @@ pub struct PlaylistAttributes {
#[derive(Debug, Clone, Default)]
pub struct PlaylistAttributeKinds(pub Vec<PlaylistAttributeKind>);
impl Deref for PlaylistAttributeKinds {
type Target = Vec<PlaylistAttributeKind>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(PlaylistAttributeKinds, Vec<PlaylistAttributeKind>);
from_repeated_enum!(PlaylistAttributeKind, PlaylistAttributeKinds);
#[derive(Debug, Clone, Default)]
pub struct PlaylistFormatAttribute(pub HashMap<String, String>);
impl Deref for PlaylistFormatAttribute {
type Target = HashMap<String, String>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(PlaylistFormatAttribute, HashMap<String, String>);
#[derive(Debug, Clone)]
pub struct PlaylistItemAttributes {
@ -69,12 +62,7 @@ pub struct PlaylistItemAttributes {
#[derive(Debug, Clone, Default)]
pub struct PlaylistItemAttributeKinds(pub Vec<PlaylistItemAttributeKind>);
impl Deref for PlaylistItemAttributeKinds {
type Target = Vec<PlaylistItemAttributeKind>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(PlaylistItemAttributeKinds, Vec<PlaylistItemAttributeKind>);
from_repeated_enum!(PlaylistItemAttributeKind, PlaylistItemAttributeKinds);

View file

@ -1,10 +1,10 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use crate::util::try_from_repeated_message;
use crate::util::{impl_deref_wrapped, try_from_repeated_message};
use super::{
attribute::{PlaylistAttributes, PlaylistItemAttributes},
@ -27,12 +27,7 @@ pub struct PlaylistItem {
#[derive(Debug, Clone, Default)]
pub struct PlaylistItems(pub Vec<PlaylistItem>);
impl Deref for PlaylistItems {
type Target = Vec<PlaylistItem>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(PlaylistItems, Vec<PlaylistItem>);
#[derive(Debug, Clone)]
pub struct PlaylistItemList {
@ -56,12 +51,7 @@ pub struct PlaylistMetaItem {
#[derive(Debug, Clone, Default)]
pub struct PlaylistMetaItems(pub Vec<PlaylistMetaItem>);
impl Deref for PlaylistMetaItems {
type Target = Vec<PlaylistMetaItem>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(PlaylistMetaItems, Vec<PlaylistMetaItem>);
impl TryFrom<&PlaylistItemMessage> for PlaylistItem {
type Error = librespot_core::Error;

View file

@ -1,14 +1,14 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use protobuf::Message;
use crate::{
request::{MercuryRequest, RequestResult},
util::{from_repeated_enum, try_from_repeated_message},
util::{from_repeated_enum, impl_deref_wrapped, try_from_repeated_message},
Metadata,
};
@ -29,12 +29,7 @@ use protocol::playlist4_external::GeoblockBlockingType as Geoblock;
#[derive(Debug, Clone, Default)]
pub struct Geoblocks(Vec<Geoblock>);
impl Deref for Geoblocks {
type Target = Vec<Geoblock>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Geoblocks, Vec<Geoblock>);
#[derive(Debug, Clone)]
pub struct Playlist {
@ -58,22 +53,12 @@ pub struct Playlist {
#[derive(Debug, Clone, Default)]
pub struct Playlists(pub Vec<SpotifyId>);
impl Deref for Playlists {
type Target = Vec<SpotifyId>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Playlists, Vec<SpotifyId>);
#[derive(Debug, Clone)]
pub struct RootPlaylist(pub SelectedListContent);
impl Deref for RootPlaylist {
type Target = SelectedListContent;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(RootPlaylist, SelectedListContent);
#[derive(Debug, Clone)]
pub struct SelectedListContent {

View file

@ -1,7 +1,7 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use crate::{
@ -9,7 +9,7 @@ use crate::{
attribute::{PlaylistUpdateAttributes, PlaylistUpdateItemAttributes},
item::PlaylistItems,
},
util::try_from_repeated_message,
util::{impl_deref_wrapped, try_from_repeated_message},
};
use librespot_protocol as protocol;
@ -32,12 +32,7 @@ pub struct PlaylistOperation {
#[derive(Debug, Clone, Default)]
pub struct PlaylistOperations(pub Vec<PlaylistOperation>);
impl Deref for PlaylistOperations {
type Target = Vec<PlaylistOperation>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(PlaylistOperations, Vec<PlaylistOperation>);
#[derive(Debug, Clone)]
pub struct PlaylistOperationAdd {

View file

@ -1,6 +1,9 @@
use std::{fmt::Debug, ops::Deref};
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
use crate::util::from_repeated_enum;
use crate::util::{from_repeated_enum, impl_deref_wrapped};
use librespot_protocol as protocol;
use protocol::playlist_permission::Capabilities as CapabilitiesMessage;
@ -19,12 +22,7 @@ pub struct Capabilities {
#[derive(Debug, Clone, Default)]
pub struct PermissionLevels(pub Vec<PermissionLevel>);
impl Deref for PermissionLevels {
type Target = Vec<PermissionLevel>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(PermissionLevels, Vec<PermissionLevel>);
impl From<&CapabilitiesMessage> for Capabilities {
fn from(playlist: &CapabilitiesMessage) -> Self {

View file

@ -1,5 +1,9 @@
use std::{fmt::Debug, ops::Deref};
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
use crate::util::impl_deref_wrapped;
use crate::util::{from_repeated_enum, from_repeated_message};
use protocol::metadata::Restriction as RestrictionMessage;
@ -20,22 +24,12 @@ pub struct Restriction {
#[derive(Debug, Clone, Default)]
pub struct Restrictions(pub Vec<Restriction>);
impl Deref for Restrictions {
type Target = Vec<Restriction>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Restrictions, Vec<Restriction>);
#[derive(Debug, Clone)]
pub struct RestrictionCatalogues(pub Vec<RestrictionCatalogue>);
impl Deref for RestrictionCatalogues {
type Target = Vec<RestrictionCatalogue>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(RestrictionCatalogues, Vec<RestrictionCatalogue>);
impl Restriction {
fn parse_country_codes(country_codes: &str) -> Vec<String> {

View file

@ -1,10 +1,13 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use crate::{restriction::Restrictions, util::try_from_repeated_message};
use crate::{
restriction::Restrictions,
util::{impl_deref_wrapped, try_from_repeated_message},
};
use librespot_core::date::Date;
@ -21,12 +24,7 @@ pub struct SalePeriod {
#[derive(Debug, Clone, Default)]
pub struct SalePeriods(pub Vec<SalePeriod>);
impl Deref for SalePeriods {
type Target = Vec<SalePeriod>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(SalePeriods, Vec<SalePeriod>);
impl TryFrom<&SalePeriodMessage> for SalePeriod {
type Error = librespot_core::Error;

View file

@ -1,7 +1,7 @@
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
ops::{Deref, DerefMut},
};
use uuid::Uuid;
@ -17,7 +17,7 @@ use crate::{
external_id::ExternalIds,
restriction::Restrictions,
sale_period::SalePeriods,
util::try_from_repeated_message,
util::{impl_deref_wrapped, try_from_repeated_message},
Album, Metadata, RequestResult,
};
@ -56,12 +56,7 @@ pub struct Track {
#[derive(Debug, Clone, Default)]
pub struct Tracks(pub Vec<SpotifyId>);
impl Deref for Tracks {
type Target = Vec<SpotifyId>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(Tracks, Vec<SpotifyId>);
#[async_trait]
impl InnerAudioItem for Track {

View file

@ -37,3 +37,22 @@ macro_rules! try_from_repeated_message {
}
pub(crate) use try_from_repeated_message;
macro_rules! impl_deref_wrapped {
($wrapper:ty, $inner:ty) => {
impl Deref for $wrapper {
type Target = $inner;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for $wrapper {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
};
}
pub(crate) use impl_deref_wrapped;

View file

@ -1,6 +1,9 @@
use std::{fmt::Debug, ops::Deref};
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
use crate::util::from_repeated_message;
use crate::util::{from_repeated_message, impl_deref_wrapped};
use librespot_core::FileId;
@ -10,11 +13,6 @@ use protocol::metadata::VideoFile as VideoFileMessage;
#[derive(Debug, Clone, Default)]
pub struct VideoFiles(pub Vec<FileId>);
impl Deref for VideoFiles {
type Target = Vec<FileId>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl_deref_wrapped!(VideoFiles, Vec<FileId>);
from_repeated_message!(VideoFileMessage, VideoFiles);