rosu 0.6.0

An osu!api v1 wrapper
Documentation
use crate::model::ApprovalStatus;
use serde::{
    de::{Error, Unexpected, Visitor},
    Deserialize, Deserializer,
};
use std::{
    convert::TryFrom,
    fmt::{Formatter, Result as FmtResult},
};

struct ApprovalStatusVisitor;

impl<'de> Visitor<'de> for ApprovalStatusVisitor {
    type Value = ApprovalStatus;

    fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
        f.write_str("an i8 or a string")
    }

    fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
        match v {
            "4" | "loved" => Ok(ApprovalStatus::Loved),
            "3" | "qualified" => Ok(ApprovalStatus::Qualified),
            "2" | "approved" => Ok(ApprovalStatus::Approved),
            "1" | "ranked" => Ok(ApprovalStatus::Ranked),
            "0" | "pending" => Ok(ApprovalStatus::Pending),
            "-1" | "wip" => Ok(ApprovalStatus::WIP),
            "-2" | "graveyard" => Ok(ApprovalStatus::Graveyard),
            _ => Err(Error::invalid_value(
                Unexpected::Str(v),
                &r#"
            "4", "loved",
            "3", qualified",
            "2", "approved",
            "1", "ranked",
            "0", "pending",
            "-1", "wip",
            "-2", or "graveyard"
            "#,
            )),
        }
    }

    fn visit_i64<E: Error>(self, v: i64) -> Result<Self::Value, E> {
        ApprovalStatus::try_from(v as i8)
            .map_err(|_| Error::invalid_value(Unexpected::Signed(v), &"value between -2 and 4"))
    }

    fn visit_u64<E: Error>(self, v: u64) -> Result<Self::Value, E> {
        ApprovalStatus::try_from(v as i8)
            .map_err(|_| Error::invalid_value(Unexpected::Unsigned(v), &"value between -2 and 4"))
    }
}

impl<'de> Deserialize<'de> for ApprovalStatus {
    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
        d.deserialize_any(ApprovalStatusVisitor)
    }
}