aede_core/model/
composers.rs1use super::{Catalog, EntityKind, Id};
3use std::collections::{BTreeMap, BTreeSet};
4impl Catalog {
5 pub fn composers_by_release(&self) -> BTreeMap<Id, BTreeSet<Id>> {
9 let mut credits: BTreeMap<(EntityKind, Id), BTreeSet<Id>> = BTreeMap::new();
12 for credit in self
13 .credits
14 .iter()
15 .filter(|credit| credit.role == "composer")
16 {
17 if self.artist(credit.artist_id).is_some() {
18 credits
19 .entry((credit.entity_kind, credit.entity_id))
20 .or_default()
21 .insert(credit.artist_id);
22 }
23 }
24 let mut result = BTreeMap::new();
25 if credits.is_empty() {
26 return result;
27 }
28 for release in &self.releases {
29 let mut composers = credits
30 .get(&(EntityKind::Release, release.id))
31 .cloned()
32 .unwrap_or_default();
33 for id in &release.track_ids {
34 let Some(track) = self.track(*id) else {
35 continue;
36 };
37 for target in [
38 (EntityKind::Track, track.id),
39 (EntityKind::Recording, track.recording_id),
40 ] {
41 if let Some(artists) = credits.get(&target) {
42 composers.extend(artists);
43 }
44 }
45 if let Some(recording) = self.recording(track.recording_id) {
46 for work in &recording.work_ids {
47 if let Some(artists) = credits.get(&(EntityKind::Work, *work)) {
48 composers.extend(artists);
49 }
50 }
51 }
52 }
53 if !composers.is_empty() {
54 result.insert(release.id, composers);
55 }
56 }
57 result
58 }
59}