1use std::str::FromStr;
2
3use anyhow::bail;
4use clap::ValueEnum;
5use serde::{Deserialize, Serialize};
6
7use crate::Level;
8
9#[derive(Serialize, Deserialize, Debug, Clone)]
10pub struct PlaylistMeta {
11 pub name: String,
12 #[serde(rename = "roundLength")]
13 pub round_length: f32,
14 #[serde(rename = "shufflePlaylist")]
15 pub shuffle: bool,
16}
17
18impl FromStr for PlaylistMeta {
19 type Err = anyhow::Error;
20
21 fn from_str(s: &str) -> Result<Self, Self::Err> {
22 let Some((name, rest)) = s.split_once(',') else {
23 bail!("MetaData needs 'name' 'round' 'shuffle' separated by ','");
24 };
25 let Some((round_length, shuffle)) = rest.split_once(',') else {
26 bail!("MetaData needs 'name' 'round' 'shuffle' separated by ','");
27 };
28 let name = name.to_string();
29 let round_length = round_length.parse()?;
30 let shuffle = shuffle.to_lowercase() == "y";
31 Ok(Self {
32 name,
33 round_length,
34 shuffle,
35 })
36 }
37}
38
39#[derive(Serialize, Deserialize, Debug)]
40pub struct Playlist {
41 #[serde(flatten)]
42 pub meta: PlaylistMeta,
43 #[serde(rename = "amountOfLevels")]
44 level_count: usize,
45 levels: Vec<Level>,
46}
47
48#[derive(ValueEnum, Clone, Copy, Debug)]
50pub enum PurgeStrata {
51 Uid,
52 }
54
55impl PurgeStrata {
56 fn purge(&mut self, level: &Level, list: &[String]) -> bool {
57 let mut i = list.iter();
58 match self {
59 PurgeStrata::Uid => i.any(|i| level.uid == *i),
60 }
62 }
63}
64
65impl Playlist {
66 pub fn new(meta: PlaylistMeta, levels: Vec<Level>) -> Playlist {
67 Self {
68 meta,
69 level_count: levels.len(),
70 levels,
71 }
72 }
73
74 pub fn purge_duplicate(&mut self, mut strategy: PurgeStrata) -> usize {
75 let mut l = vec![];
76 let mut i = 0;
77 self.levels.retain(|p| {
78 let s = strategy.purge(p, &l);
79 if s {
80 i += 1;
81 } else {
82 l.push(p.uid.clone())
84 }
85 !s
86 });
87 self.level_count = self.levels.len();
88 i
89 }
90
91 pub fn get_name(&self) -> &str {
92 &self.meta.name
93 }
94
95 pub fn merge(&mut self, mut two: Playlist) {
96 self.levels.append(&mut two.levels);
97 self.level_count = self.levels.len();
98 }
99}