Skip to main content

selene_core/library/
collection.rs

1use std::{convert::Infallible, str::FromStr};
2
3use blake3::Hash;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    database::EntryId,
8    library::{album::AlbumId, artist::ArtistId, cover_art::CoverArt, track::TrackId},
9};
10
11pub mod frontend_impls;
12pub mod trait_impls;
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
15pub struct Collection {
16    id: CollectionId,
17    pub name: String,
18    pub cover_art: Option<CoverArt>,
19
20    pub collectables: Vec<Collectable>,
21}
22
23impl Collection {
24    /// Creates a new collection with the input name
25    ///
26    /// # Errors
27    ///
28    /// This function will return `None` if the input name is empty or is trimmed to an empty string
29    fn new(name: String) -> Option<Self> {
30        let id = CollectionId::from_str(&name).unwrap();
31
32        Some(Self {
33            id,
34            name,
35            cover_art: None,
36            collectables: Vec::new(),
37        })
38    }
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
42pub enum Collectable {
43    Track(TrackId),
44    Artist(ArtistId),
45    Album(AlbumId),
46    Collection(CollectionId),
47}
48
49#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq, Hash)]
50pub struct CollectionId {
51    id: Hash,
52}
53
54impl EntryId for CollectionId {
55    type Entry = Collection;
56}
57
58impl std::ops::Deref for CollectionId {
59    type Target = Hash;
60
61    fn deref(&self) -> &Self::Target {
62        &self.id
63    }
64}
65
66impl FromStr for CollectionId {
67    type Err = Infallible;
68
69    fn from_str(s: &str) -> Result<Self, Self::Err> {
70        Ok(Self {
71            id: blake3::hash(s.as_bytes()),
72        })
73    }
74}