use crate::value_objects::ContentType; const SYNC_STATUS_RUNNING: &str = "running"; #[derive(Debug, Clone)] pub struct LibraryItem { id: String, provider_id: String, external_id: String, title: String, content_type: ContentType, duration_secs: u32, series_name: Option, season_number: Option, episode_number: Option, year: Option, genres: Vec, tags: Vec, collection_id: Option, collection_name: Option, collection_type: Option, thumbnail_url: Option, synced_at: String, } impl LibraryItem { pub fn new( provider_id: impl Into, external_id: impl Into, title: impl Into, content_type: ContentType, duration_secs: u32, synced_at: impl Into, ) -> Self { let provider_id = provider_id.into(); let external_id = external_id.into(); let id = format!("{}::{}", provider_id, external_id); Self { id, provider_id, external_id, title: title.into(), content_type, duration_secs, series_name: None, season_number: None, episode_number: None, year: None, genres: Vec::new(), tags: Vec::new(), collection_id: None, collection_name: None, collection_type: None, thumbnail_url: None, synced_at: synced_at.into(), } } pub fn from_persistence( id: String, provider_id: String, external_id: String, title: String, content_type: ContentType, duration_secs: u32, series_name: Option, season_number: Option, episode_number: Option, year: Option, genres: Vec, tags: Vec, collection_id: Option, collection_name: Option, collection_type: Option, thumbnail_url: Option, synced_at: String, ) -> Self { Self { id, provider_id, external_id, title, content_type, duration_secs, series_name, season_number, episode_number, year, genres, tags, collection_id, collection_name, collection_type, thumbnail_url, synced_at, } } pub fn id(&self) -> &str { &self.id } pub fn provider_id(&self) -> &str { &self.provider_id } pub fn external_id(&self) -> &str { &self.external_id } pub fn title(&self) -> &str { &self.title } pub fn content_type(&self) -> &ContentType { &self.content_type } pub fn duration_secs(&self) -> u32 { self.duration_secs } pub fn series_name(&self) -> Option<&str> { self.series_name.as_deref() } pub fn season_number(&self) -> Option { self.season_number } pub fn episode_number(&self) -> Option { self.episode_number } pub fn year(&self) -> Option { self.year } pub fn genres(&self) -> &[String] { &self.genres } pub fn tags(&self) -> &[String] { &self.tags } pub fn collection_id(&self) -> Option<&str> { self.collection_id.as_deref() } pub fn collection_name(&self) -> Option<&str> { self.collection_name.as_deref() } pub fn collection_type(&self) -> Option<&str> { self.collection_type.as_deref() } pub fn thumbnail_url(&self) -> Option<&str> { self.thumbnail_url.as_deref() } pub fn synced_at(&self) -> &str { &self.synced_at } } #[derive(Debug, Clone)] pub struct LibraryCollection { id: String, name: String, collection_type: Option, } impl LibraryCollection { pub fn new(id: impl Into, name: impl Into) -> Self { Self { id: id.into(), name: name.into(), collection_type: None, } } pub fn from_persistence( id: String, name: String, collection_type: Option, ) -> Self { Self { id, name, collection_type, } } pub fn id(&self) -> &str { &self.id } pub fn name(&self) -> &str { &self.name } pub fn collection_type(&self) -> Option<&str> { self.collection_type.as_deref() } } #[derive(Debug, Clone)] pub struct LibrarySyncResult { provider_id: String, items_found: u32, duration_ms: u64, error: Option, } impl LibrarySyncResult { pub fn new( provider_id: impl Into, items_found: u32, duration_ms: u64, ) -> Self { Self { provider_id: provider_id.into(), items_found, duration_ms, error: None, } } pub fn with_error( provider_id: impl Into, duration_ms: u64, error: impl Into, ) -> Self { Self { provider_id: provider_id.into(), items_found: 0, duration_ms, error: Some(error.into()), } } pub fn from_persistence( provider_id: String, items_found: u32, duration_ms: u64, error: Option, ) -> Self { Self { provider_id, items_found, duration_ms, error, } } pub fn provider_id(&self) -> &str { &self.provider_id } pub fn items_found(&self) -> u32 { self.items_found } pub fn duration_ms(&self) -> u64 { self.duration_ms } pub fn error(&self) -> Option<&str> { self.error.as_deref() } } #[derive(Debug, Clone)] pub struct LibrarySyncLogEntry { id: i64, provider_id: String, started_at: String, finished_at: Option, items_found: u32, status: String, error_msg: Option, } impl LibrarySyncLogEntry { pub fn new(id: i64, provider_id: impl Into, started_at: impl Into) -> Self { Self { id, provider_id: provider_id.into(), started_at: started_at.into(), finished_at: None, items_found: 0, status: SYNC_STATUS_RUNNING.to_string(), error_msg: None, } } pub fn from_persistence( id: i64, provider_id: String, started_at: String, finished_at: Option, items_found: u32, status: String, error_msg: Option, ) -> Self { Self { id, provider_id, started_at, finished_at, items_found, status, error_msg, } } pub fn id(&self) -> i64 { self.id } pub fn provider_id(&self) -> &str { &self.provider_id } pub fn started_at(&self) -> &str { &self.started_at } pub fn finished_at(&self) -> Option<&str> { self.finished_at.as_deref() } pub fn items_found(&self) -> u32 { self.items_found } pub fn status(&self) -> &str { &self.status } pub fn error_msg(&self) -> Option<&str> { self.error_msg.as_deref() } } #[derive(Debug, Clone)] pub struct ShowSummary { series_name: String, episode_count: u32, season_count: u32, thumbnail_url: Option, genres: Vec, } impl ShowSummary { pub fn new( series_name: impl Into, episode_count: u32, season_count: u32, ) -> Self { Self { series_name: series_name.into(), episode_count, season_count, thumbnail_url: None, genres: Vec::new(), } } pub fn from_persistence( series_name: String, episode_count: u32, season_count: u32, thumbnail_url: Option, genres: Vec, ) -> Self { Self { series_name, episode_count, season_count, thumbnail_url, genres, } } pub fn series_name(&self) -> &str { &self.series_name } pub fn episode_count(&self) -> u32 { self.episode_count } pub fn season_count(&self) -> u32 { self.season_count } pub fn thumbnail_url(&self) -> Option<&str> { self.thumbnail_url.as_deref() } pub fn genres(&self) -> &[String] { &self.genres } } #[derive(Debug, Clone)] pub struct SeasonSummary { season_number: u32, episode_count: u32, thumbnail_url: Option, } impl SeasonSummary { pub fn new(season_number: u32, episode_count: u32) -> Self { Self { season_number, episode_count, thumbnail_url: None, } } pub fn from_persistence( season_number: u32, episode_count: u32, thumbnail_url: Option, ) -> Self { Self { season_number, episode_count, thumbnail_url, } } pub fn season_number(&self) -> u32 { self.season_number } pub fn episode_count(&self) -> u32 { self.episode_count } pub fn thumbnail_url(&self) -> Option<&str> { self.thumbnail_url.as_deref() } } #[cfg(test)] #[path = "tests/library.rs"] mod tests;