use mongod::{ assert_reference_of, derive::{Model, Referencable}, reference_of, Model, Referencable, Reference, Validate, }; use serde::{Deserialize, Serialize}; use crate::{ library::{track::Track, user::User}, route::ToAPI, }; #[derive(Debug, Clone, Serialize, Deserialize, Model, Referencable)] pub struct Playlist { pub _id: String, pub owner: Reference, pub title: String, pub visibility: Visibility, pub tracks: Vec, } impl Playlist { pub async fn create( owner: User, title: &str, visibility: Visibility, tracks: &[String], ) -> Option { let mut tracks_ref = vec![]; for track in tracks { tracks_ref.push(reference_of!(Track, track)?); } Some(Self { _id: uuid::Uuid::new_v4().to_string(), owner: owner.reference(), title: title.to_string(), visibility, tracks: tracks_ref, }) } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum Visibility { Private, Public, } impl Validate for Playlist { async fn validate(&self) -> Result<(), String> { assert_reference_of!(self.owner, User); for track in &self.tracks { assert_reference_of!(track, Track); } Ok(()) } } impl ToAPI for Playlist { async fn api(&self) -> serde_json::Value { serde_json::json!({ "id": self._id, "owner": self.owner.id(), "title": self.title, "tracks": self.tracks.iter().map(|x| x.id()).collect::>() }) } }