rosu 0.6.0

An osu!api v1 wrapper
Documentation
use serde::{
    de::{Error, Visitor},
    Deserializer,
};
use std::{
    fmt::{Formatter, Result as FmtResult},
    str::FromStr,
};

struct F32Visitor;

impl<'de> Visitor<'de> for F32Visitor {
    type Value = Option<f32>;

    fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
        f.write_str("a f32, a stringified number, or null")
    }

    fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
        f32::from_str(v).map(Some).map_err(Error::custom)
    }

    fn visit_f64<E: Error>(self, v: f64) -> Result<Self::Value, E> {
        Ok(Some(v as f32))
    }

    fn visit_some<D: Deserializer<'de>>(self, d: D) -> Result<Self::Value, D::Error> {
        d.deserialize_any(Self)
    }

    #[inline]
    fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
        Ok(None)
    }
}

pub(crate) fn to_maybe_f32<'de, D: Deserializer<'de>>(d: D) -> Result<Option<f32>, D::Error> {
    d.deserialize_option(F32Visitor)
}

pub(crate) fn to_f32<'de, D: Deserializer<'de>>(d: D) -> Result<f32, D::Error> {
    Ok(d.deserialize_option(F32Visitor)?.unwrap_or(0.0))
}