artifacts: split out each artifact source into a submodule, move archive.rs into artifacts/beets.rs

This commit is contained in:
2026-06-15 15:27:20 +02:00
parent 59a03eb72c
commit 5595b02211
7 changed files with 98 additions and 90 deletions
+136
View File
@@ -0,0 +1,136 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
pub mod bandcamp;
pub mod mixxx;
pub mod beets;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum SourceID {
Bandcamp(u64),
Mixxx,
Beets
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct Artist {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub bio: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub location: Option<String>,
pub sources: Vec<SourceID>
}
impl PartialEq for Artist {
fn eq(&self, other: &Self) -> bool {
if self.name != other.name {
return false;
}
true
}
fn ne(&self, other: &Self) -> bool {
!self.eq(other)
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
pub struct Album {
pub title: String,
pub artist: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub about: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub credits: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub release_date: Option<DateTime<Utc>>,
pub sources: Vec<SourceID>
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct Track {
pub title: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub year: Option<u32>,
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub genres: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub album: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub artist: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bpm: Option<f64>,
pub sources: Vec<SourceID>
}
impl PartialEq for Track {
fn eq(&self, other: &Self) -> bool {
if self.title != other.title {
return false;
}
if self.artist.is_some() && self.artist != other.artist {
return false;
}
if self.album.is_some() && self.album != other.album {
return false;
}
true
}
fn ne(&self, other: &Self) -> bool {
!self.eq(other)
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum Artifact {
Artist(Artist),
Album(Album),
Track(Track)
}
macro_rules! merge_fields {
($this:expr, $that:expr, $field:tt) => {
if $this.$field.is_none() {
$this.$field = $that.$field;
}
};
($this:tt, $that:tt, $($fields:tt),+) => {
$(
merge_fields!($this, $that, $fields);
)+
}
}
impl Artifact {
pub fn merge(&mut self, other: Artifact) {
if *self != other {
return;
}
match (self, other) {
(Artifact::Track(this_track), Artifact::Track(that_track)) => {
merge_fields!(this_track, that_track, album, label, year, artist, bpm);
// FIXME: genres
},
(Artifact::Album(this_album), Artifact::Album(that_album)) => {
merge_fields!(this_album, that_album, about, credits, release_date);
},
(Artifact::Artist(this_artist), Artifact::Artist(that_artist)) => {
merge_fields!(this_artist, that_artist, bio, location);
},
_ => ()
}
}
}