termusiclib/podcast/
podcast.rs1use std::cmp::Ordering;
2
3use chrono::{DateTime, Utc};
4
5use crate::utils::StringUtils;
6
7use super::{
8 Menuable, PODCAST_UNPLAYED_TOTALS_LENGTH,
9 episode::{Episode, EpisodeNoId},
10};
11
12#[derive(Debug, Clone)]
15pub struct Podcast {
16 pub id: i64,
17 pub title: String,
18 pub sort_title: String,
19 pub url: String,
20 pub description: Option<String>,
21 pub author: Option<String>,
22 pub explicit: Option<bool>,
23 pub last_checked: DateTime<Utc>,
24 pub episodes: Vec<Episode>,
25 pub image_url: Option<String>,
26}
27
28impl Podcast {
29 #[must_use]
31 pub fn num_unplayed(&self) -> usize {
32 self.episodes
33 .iter()
34 .map(|ep| usize::from(!ep.is_played()))
35 .sum()
36 }
37}
38
39impl Menuable for Podcast {
40 fn get_id(&self) -> i64 {
42 self.id
43 }
44
45 fn get_title(&self, length: usize) -> String {
47 let mut title_length = length;
48
49 if length > PODCAST_UNPLAYED_TOTALS_LENGTH {
52 let meta_str = format!("({}/{})", self.num_unplayed(), self.episodes.len());
53 title_length = length - meta_str.chars().count() - 3;
54
55 let out = self.title.substr(0, title_length);
56
57 format!(
58 " {out} {meta_str:>width$} ",
59 width = length - out.grapheme_len() - 3
60 ) } else {
62 format!(" {} ", self.title.substr(0, title_length - 2))
63 }
64 }
65
66 fn is_played(&self) -> bool {
67 self.num_unplayed() == 0
68 }
69}
70
71impl PartialEq for Podcast {
72 fn eq(&self, other: &Self) -> bool {
73 self.sort_title == other.sort_title
74 }
75}
76impl Eq for Podcast {}
77
78impl PartialOrd for Podcast {
79 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
80 Some(self.cmp(other))
81 }
82}
83
84impl Ord for Podcast {
85 fn cmp(&self, other: &Self) -> Ordering {
86 self.sort_title.cmp(&other.sort_title)
87 }
88}
89
90#[derive(Debug, Clone, Eq, PartialEq)]
94#[allow(clippy::module_name_repetitions)]
95pub struct PodcastNoId {
96 pub title: String,
97 pub url: String,
98 pub description: Option<String>,
99 pub author: Option<String>,
100 pub explicit: Option<bool>,
101 pub last_checked: DateTime<Utc>,
102 pub episodes: Vec<EpisodeNoId>,
103 pub image_url: Option<String>,
104}