1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use json::JsonValue;
use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::{level::LevelError, Level};

#[derive(Serialize, Deserialize, Debug)]
pub struct Playlist {
    name: String,
    #[serde(rename = "amountOfLevels")]
    amount_of_levels: usize,
    #[serde(rename = "roundLength")]
    round_length: f32,
    #[serde(rename = "shufflePlaylist")]
    shuffle: bool,
    levels: Vec<Level>,
}

impl Playlist {
    pub fn new(name: &str, round_length: f32, shuffle: bool, levels: Vec<Level>) -> Playlist {
        Self {
            name: name.to_string(),
            amount_of_levels: levels.len(),
            round_length,
            shuffle,
            levels,
        }
    }

    pub fn from_json(
        name: &str,
        round_length: f32,
        shuffle: bool,
        mut json: JsonValue,
    ) -> Result<Playlist, PlaylistError> {
        let mut levels = Vec::new();
        let mut i = 0;

        if json.has_key("favorites") {
            json = json["favorites"].take();
        } else if json.has_key("levels") {
            json = json["levels"].take();
        } else if json.has_key("records") {
            json = json["records"].take();
        } else if !json.is_array() {
            return Err(PlaylistError::JsonNoArray(json));
        }

        while !json[i].is_empty() {
            let l = Level::try_from(json[i].take())?;
            levels.push(l);
            i += 1;
        }
        Ok(Playlist::new(name, round_length, shuffle, levels))
    }

    pub fn get_name(&self) -> &str {
        &self.name
    }
}

#[derive(Error, Debug)]
pub enum PlaylistError {
    #[error("can not find array of levels")]
    JsonNoArray(JsonValue),
    #[error(transparent)]
    LevelError(#[from] LevelError),
}