ncm_meta 0.2.11

music meta utils for ncmc
Documentation
use miniserde::{de, make_place, Deserialize};

#[derive(Deserialize, Debug)]
#[allow(dead_code)]
pub(crate) struct MusicMeta {
    #[serde(rename = "musicId")]
    pub music_id: MusicId,
    #[serde(rename = "musicName")]
    pub music_name: String,
    pub artist: Vec<(String, MusicId)>,
    pub album: String,
    #[serde(rename = "albumPic")]
    pub album_pic: String,
    pub format: String,
}

make_place!(Place);
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) enum MusicId {
    Num(u32),
    Str(String),
}

impl de::Visitor for Place<MusicId> {
    fn string(&mut self, s: &str) -> miniserde::Result<()> {
        let out = match s.parse::<u32>() {
            Ok(value) => MusicId::Num(value),
            Err(..) => MusicId::Str(s.to_string()),
        };
        self.out = Some(out);

        Ok(())
    }

    fn nonnegative(&mut self, n: u64) -> miniserde::Result<()> {
        let value = n as u32;
        self.out = Some(MusicId::Num(value));

        Ok(())
    }
}

impl de::Deserialize for MusicId {
    fn begin(out: &mut Option<Self>) -> &mut dyn de::Visitor {
        Place::new(out)
    }
}

#[cfg(test)]
mod tests {
    use std::{fs, path::PathBuf};

    use miniserde::json;

    use super::*;

    #[testing::fixture("../ncmc/tests/input/*.json")]
    fn test_deserialize(input: PathBuf) {
        let data = fs::read(&input).unwrap();
        let meta = String::from_utf8_lossy(&data);
        match json::from_str::<MusicMeta>(&meta) {
            Ok(_) => {}
            Err(err) => {
                eprintln!("{meta}");
                panic!("{err}");
            }
        };
    }
}