1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
use chrono::NaiveDate;
use lucene_query_builder::QueryBuilder;
use serde::{Deserialize, Serialize};
use super::{Include, Relationship, Subquery};
use crate::date_format;
use crate::entity::alias::Alias;
use crate::entity::artist_credit::ArtistCredit;
use crate::entity::genre::Genre;
use crate::entity::label::LabelInfo;
use crate::entity::recording::Recording;
use crate::entity::relations::Relation;
use crate::entity::release_group::ReleaseGroup;
use crate::entity::tag::Tag;
use crate::entity::BrowseBy;
/// A MusicBrainz release represents the unique release (i.e. issuing) of a product on a specific
/// date with specific release information such as the country, label, barcode and packaging.
/// If you walk into a store and purchase an album or single, they are each represented in
/// MusicBrainz as one release.
///
/// Each release belongs to a release group and contains at least one medium (commonly referred to
/// as a disc when talking about a CD release). Each medium has a tracklist.
/// A medium is the actual physical medium that stores the audio content. This means that each CD
/// in a multi-disc release will be entered as separate mediums within the release, and that both
/// sides of a vinyl record or cassette will exist on one medium. Mediums have a format (e.g. CD,
/// DVD, vinyl, and cassette) and can optionally also have a title. Sometimes a medium can be a
/// side of a disc. For example, the two sides of a hybrid SACD (the CD side and the SACD side)
/// should be entered as two mediums.
/// Tracklists represent the set and ordering of tracks as listed on a liner, and the same tracklist
/// can appear on more than one release. For example, a boxset compilation that contains previously
/// released CDs would share the same tracklists as the separate releases.
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(rename_all(deserialize = "kebab-case"))]
pub struct Release {
/// See [MusicBrainz Identifier](https://musicbrainz.org/doc/MusicBrainz_Identifier).
pub id: String,
/// The title of the release.
pub title: String,
#[serde(rename = "status-id")]
pub status_id: Option<String>,
/// The status describes how "official" a release is.
pub status: Option<ReleaseStatus>,
/// The date the release was issued.
#[serde(deserialize_with = "date_format::deserialize_opt")]
#[serde(default)]
pub date: Option<NaiveDate>,
/// The country the release was issued in.
pub country: Option<String>,
/// Data quality indicates how good the data for a release is. It is not a mark of how good or
/// bad the music itself is - for that, use ratings.
pub quality: Option<ReleaseQuality>,
/// The barcode, if the release has one. The most common types found on releases are 12-digit
/// UPCs and 13-digit EANs.
pub barcode: Option<String>,
/// The disambiguation comments are fields in the database used to help distinguish identically
/// named artists, labels and other entities.
pub disambiguation: Option<String>,
#[serde(rename = "packaging-id")]
pub packaging_id: Option<String>,
/// The physical packaging that accompanies the release. See the
/// [list of packaging](https://musicbrainz.org/doc/Release/Packaging) for more information.
pub packaging: Option<ReleasePackaging>,
pub relations: Option<Vec<Relation>>,
/// The release group associated with this release.
pub release_group: Option<ReleaseGroup>,
/// Artist credits indicate who is the main credited artist (or artists) for releases, release
/// groups, tracks and recordings, and how they are credited.
pub artist_credit: Option<Vec<ArtistCredit>>,
pub media: Option<Vec<Media>>,
/// The label which issued the release. There may be more than one.
pub label_info: Option<Vec<LabelInfo>>,
pub tags: Option<Vec<Tag>>,
/// Aliases are alternate names for a release.
pub aliases: Option<Vec<Alias>>,
/// Genres are currently supported in MusicBrainz as part of the tag system.
pub genres: Option<Vec<Genre>>,
/// Annotations are text fields, functioning like a miniature wiki, that can be added to any
/// existing artists, labels, recordings, releases, release groups and works.
pub annotation: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct ReleaseTextRepresentation {
/// The language a release's track list is written in. The possible values are taken from the ISO
/// 639-3 standard.
pub language: Language,
/// The script used to write the release's track list. The possible values are taken from the
/// ISO 15924 standard.
pub script: ReleaseScript,
}
/// The script used to write the release's track list. The possible values are taken from the
/// [ISO 15924](https://en.wikipedia.org/wiki/ISO_15924) standard.
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub enum ReleaseScript {
/* TODO: we need to test all posible values to build the enum see https://musicbrainz.org/doc/Release */
/// ## Latin (also known as Roman or, incorrectly, "English")
/// Latin is the most common script, and usually the correct choice. It is used
/// for all Western European languages, and many others. It is also the most common script used for transliterations.
Latn,
}
/* TODO: we need to test all posible values to build the enum see https://musicbrainz.org/doc/Release */
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub enum Language {
Eng,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all(deserialize = "lowercase"))]
pub enum ReleaseQuality {
/// The release needs serious fixes, or its existence is hard to prove (but it's not clearly fake).
Low,
/// All available data has been added, if possible including cover art with liner info that
/// proves it.
High,
/// This is the default setting - technically "unknown" if the quality has never been modified,
/// "normal" if it has.
Normal,
Unknown,
None,
}
/// The release status describes how "official" a release is.
/// Note that this enum is `non_exhaustive`; The list of release types is subject to change and
/// these changes are only reflected in the DB, not in actual MB code.
/// Variants are derived from the `release_status` table in the MusicBrainz database.
#[non_exhaustive]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub enum ReleaseStatus {
/// Any release officially sanctioned by the artist and/or their record company. Most releases
/// will fit into this category.
Official,
/// A give-away release or a release intended to promote an upcoming official release (e.g.
/// pre-release versions, releases included with a magazine, versions supplied to radio DJs
/// for air-play).
Promotion,
/// An unofficial/underground release that was not sanctioned by the artist and/or the record
/// company. This includes unofficial live recordings and pirated releases.
Bootleg,
/// An alternate version of a release where the titles have been changed. These don't correspond
/// to any real release and should be linked to the original release using the transl(iter)ation
/// [transl(iter)ation relationship](https://musicbrainz.org/relationship/fc399d47-23a7-4c28-bfcf-0607a562b644).
#[serde(rename = "Pseudo-Release")]
PseudoRelease,
/// Any release_status that does not yet have a corresponding variant in this enum.
/// If you ever see a `ReleaseStatus::UnrecognizedReleaseStatus` in the wild, let us know and file an issue/pull request!
#[serde(other)]
UnrecognizedReleaseStatus,
}
/// The type of packaging of a MusicBrainz release entity.
/// Note that this enum is `non_exhaustive`; The list of release types is subject to change and
/// these changes are only reflected in the DB, not in actual MB code.
/// Variants are derived from the `release_packaging` table in the MusicBrainz database.
#[non_exhaustive]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub enum ReleasePackaging {
Book,
Box,
#[serde(rename = "Cardboard/Paper Sleeve")]
CardboardPaperSleeve,
#[serde(rename = "Cassette Case")]
CassetteCase,
/// A perfect bound book with a sleeve at the end to hold a CD
Digibook,
Digipak,
#[serde(rename = "Discbox Slider")]
DiscboxSlider,
Fatbox,
#[serde(rename = "Gatefold Cover")]
GatefoldCover,
/// The traditional CD case, made of hard, brittle plastic.
#[serde(rename = "Jewel Case")]
JewelCase,
#[serde(rename = "Keep Case")]
KeepCase,
#[serde(rename = "Plastic Sleeve")]
PlasticSleeve,
/// Plastic CD tray inside a cardboard slipcover
Slidepack,
/// A thinner jewel case, commonly used for CD singles.
#[serde(rename = "Slim Jewel Case")]
SlimJewelCase,
#[serde(rename = "Snap Case")]
SnapCase,
/// Japanese case that holds an 8cm CD. It is rectangular but can be snapped to make it more
/// compact (hence the name).
#[serde(rename = "SnapPack")]
Snappack,
#[serde(rename = "Super Jewel Box")]
SuperJewelBox,
Other,
None,
/// Any release_packaging that does not yet have a corresponding variant in this enum.
/// If you ever see a `ReleasePackaging::UnrecognizedReleasePackaging` in the wild, let us know and file an issue/pull request!
#[serde(other)]
UnrecognizedReleasePackaging,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(rename_all(deserialize = "kebab-case"))]
pub struct Media {
pub title: Option<String>,
pub position: Option<u32>,
pub track_count: u32,
pub disc_count: Option<u32>,
pub format_id: Option<String>,
pub format: Option<String>,
pub tracks: Option<Vec<Track>>,
}
/// A track is the way a recording is represented on a particular release (or, more exactly, on a
/// particular medium).
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(rename_all(deserialize = "kebab-case"))]
pub struct Track {
pub recording: Recording,
pub title: String,
pub number: String,
pub length: Option<u32>,
pub position: u32,
pub id: String,
}
#[derive(Debug, Default, Serialize, Deserialize, QueryBuilder)]
pub struct ReleaseSearchQuery {
/// (part of) any alias attached to the release group (diacritics are ignored)
alias: String,
/// the MBID of any of the release group artists
arid: String,
/// (part of) the combined credited artist name for the release group, including join phrases (e.g. "Artist X feat.")
artist: String,
/// (part of) the name of any of the release group artists
#[query_builder_field = "artistname"]
artist_name: String,
/// an Amazon ASIN for the release
asin: String,
/// the barcode for the release
barcode: String,
/// any catalog number for this release (insensitive to case, spaces and separators)
#[query_builder_field = "catno"]
catalog_number: String,
/// (part of) the release group's disambiguation comment
comment: String,
/// the 2-letter code (ISO 3166-1 alpha-2) for any country the release was released in
country: String,
/// (part of) the credited name of any of the release group artists on this particular release group
#[query_builder_field = "creditname"]
credit_name: String,
/// a release date for the release (e.g. "1980-01-22")
#[serde(deserialize_with = "date_format::deserialize_opt")]
#[serde(default)]
date: Option<NaiveDate>,
/// the total number of disc IDs attached to all mediums on the release
discids: u32,
/// the number of disc IDs attached to any one medium on the release
#[query_builder_field = "discidsmedium"]
discids_medium: u32,
/// the format of any medium in the release (insensitive to case, spaces, and separators)
format: String,
/// the MBID of any of the release labels
laid: String,
/// (part of) the name of any of the release labels
label: String,
/// the ISO 639-3 code for the release language
lang: String,
/// the number of mediums on the release
mediums: u32,
/// the format of the release (insensitive to case, spaces, and separators)
packaging: String,
/// the primary type of the release group
#[query_builder_field = "primarytype"]
primary_type: String,
/// the listed quality of the data for the release (one of "low", "normal", "high")
quality: String,
/// the MBID of any of the releases in the release group
reid: String,
/// (part of) the title of any of the releases in the release group
release: String,
/// (part of) the release's title (with the specified diacritics)
#[query_builder_field = "releaseaccent"]
release_accent: String,
/// the release group's MBID
rgid: String,
/// the ISO 15924 code for the release script
script: String,
/// any of the secondary types of the release group
#[query_builder_field = "secondarytype"]
secondary_type: String,
/// the status of any of the releases in the release group
status: String,
/// the status of any of the releases in the release group
tag: String,
/// the total number of tracks on the release
tracks: u32,
/// the number of tracks on any one medium on the release
#[query_builder_field = "tracksmedium"]
tracks_medium: u32,
/// legacy release group type field that predates the ability to set multiple types (see calculation code)
#[query_builder_field = "type"]
release_type: String,
}
impl_browse! {
Release,
(by_area, BrowseBy::Area),
(by_artist, BrowseBy::Artist),
(by_label, BrowseBy::Label),
(by_track, BrowseBy::Track),
(by_track_artist, BrowseBy::TrackArtist),
(by_recording, BrowseBy::Recording),
(by_release_group, BrowseBy::ReleaseGroup),
(by_collection, BrowseBy::Collection)
}
impl_includes!(
Release,
(with_artists, Include::Subquery(Subquery::Artists)),
(with_labels, Include::Subquery(Subquery::Labels)),
(
with_artist_relations,
Include::Relationship(Relationship::Artist)
),
(
with_work_relations,
Include::Relationship(Relationship::Work)
),
(with_url_relations, Include::Relationship(Relationship::Url)),
(
with_work_level_relations,
Include::Relationship(Relationship::WorkLevel)
),
(
with_recording_level_relations,
Include::Relationship(Relationship::RecordingLevel)
),
(with_recordings, Include::Subquery(Subquery::Recordings)),
(
with_release_groups,
Include::Subquery(Subquery::ReleaseGroups)
),
(with_tags, Include::Subquery(Subquery::Tags)),
(with_ratings, Include::Subquery(Subquery::Rating)),
(with_aliases, Include::Subquery(Subquery::Aliases)),
(with_genres, Include::Subquery(Subquery::Genres)),
(with_annotations, Include::Subquery(Subquery::Annotations)),
(
with_artist_credits,
Include::Subquery(Subquery::ArtistCredits)
)
);