use crate::{ models::{ Album, Band, BandInfo, Discograph, FeedItem, SearchAlbum, SearchBand, SearchItem, SearchTrack, }, ImageFormat, IMG_URL, }; use self::image_id::ImageId; mod image_id { pub trait ImageId { /// Get the image ID of an item /// plus a flag whether the image is an album artwork. fn img_id(&self) -> Option<(u64, bool)>; } } /// Trait for Bandcamp items with an image pub trait ImageUrl: ImageId { /// Get the URL of the item's image in the given resolution /// or [`None`] if the item does not have an image. fn img_url_fmt(&self, size: ImageFormat) -> Option { let (id, is_a) = self.img_id()?; Some(format!( "{}{}{}_{}", IMG_URL, if is_a { "a" } else { "" }, id, size.nr() )) } /// Get the URL of the item's image in maximum resolution /// or [`None`] if the item does not have an image. fn img_url(&self) -> Option { self.img_url_fmt(ImageFormat::default()) } } impl ImageId for Band { fn img_id(&self) -> Option<(u64, bool)> { self.bio_image_id.map(|id| (id, false)) } } impl ImageUrl for Band {} impl Band { /// Get the URL of the band's header image in the given resolution /// or [`None`] if the band does not have a header image. pub fn header_img_url_fmt(&self, format: ImageFormat) -> Option { self.header_image_id .map(|id| format!("{}{}_{}.jpg", IMG_URL, id, format.nr())) } /// Get the URL of the band's header image in maximum resolution /// or [`None`] if the band does not have a header image. pub fn header_img_url(&self) -> Option { self.header_img_url_fmt(ImageFormat::default()) } } impl ImageId for Album { fn img_id(&self) -> Option<(u64, bool)> { self.art_id.map(|id| (id, true)) } } impl ImageUrl for Album {} impl ImageId for Discograph { fn img_id(&self) -> Option<(u64, bool)> { self.art_id.map(|id| (id, true)) } } impl ImageUrl for Discograph {} impl ImageId for BandInfo { fn img_id(&self) -> Option<(u64, bool)> { self.image_id.map(|id| (id, false)) } } impl ImageUrl for BandInfo {} impl ImageId for SearchBand { fn img_id(&self) -> Option<(u64, bool)> { self.img_id.map(|id| (id, false)) } } impl ImageUrl for SearchBand {} impl ImageId for SearchAlbum { fn img_id(&self) -> Option<(u64, bool)> { self.art_id.map(|id| (id, true)) } } impl ImageUrl for SearchAlbum {} impl ImageId for SearchTrack { fn img_id(&self) -> Option<(u64, bool)> { self.art_id.map(|id| (id, true)) } } impl ImageUrl for SearchTrack {} impl ImageId for SearchItem { fn img_id(&self) -> Option<(u64, bool)> { match self { SearchItem::Band(band) => band.img_id(), SearchItem::Album(album) => album.img_id(), SearchItem::Track(track) => track.img_id(), } } } impl ImageUrl for SearchItem {} impl ImageId for FeedItem { fn img_id(&self) -> Option<(u64, bool)> { self.art_id.map(|id| (id, true)) } } impl ImageUrl for FeedItem {}