yandex-music 0.4.0

Rust wrapper for the Yandex Music API
Documentation
use std::fmt;
use std::time::Duration;

use serde::de::{self, Deserializer, Error, MapAccess, SeqAccess, Visitor};
use serde::{Deserialize, Serializer};

pub fn number_to_string<'de, D>(deserializer: D) -> Result<String, D::Error>
where
    D: Deserializer<'de>,
{
    let value = Deserialize::deserialize(deserializer)?;
    match value {
        serde_json::Value::Number(num) => Ok(num.to_string()),
        serde_json::Value::String(s) => Ok(s),
        _ => Err(D::Error::custom("expected number or string")),
    }
}

pub fn opt_string_to_u32<'de, D>(
    deserializer: D,
) -> Result<Option<u32>, D::Error>
where
    D: Deserializer<'de>,
{
    let value = Deserialize::deserialize(deserializer)?;
    match value {
        serde_json::Value::Number(num) => {
            Ok(Some(num.as_u64().unwrap() as u32))
        }
        serde_json::Value::String(s) => {
            s.parse::<u32>().map_err(de::Error::custom).map(Some)
        }
        _ => Ok(None),
    }
}

pub fn opt_number_to_string<'de, D>(
    deserializer: D,
) -> Result<Option<String>, D::Error>
where
    D: Deserializer<'de>,
{
    let value = Deserialize::deserialize(deserializer)?;
    match value {
        serde_json::Value::Number(num) => Ok(Some(num.to_string())),
        serde_json::Value::String(s) => Ok(Some(s)),
        _ => Ok(None),
    }
}

pub fn deserialize_maybe_vec<'de, D, T>(
    deserializer: D,
) -> Result<Vec<T>, D::Error>
where
    D: Deserializer<'de>,
    T: Deserialize<'de>,
{
    struct MaybeVecVisitor<T>(std::marker::PhantomData<T>);

    impl<'de, T> Visitor<'de> for MaybeVecVisitor<T>
    where
        T: Deserialize<'de>,
    {
        type Value = Vec<T>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("null, an object, or a sequence of objects")
        }

        fn visit_unit<E>(self) -> Result<Self::Value, E>
        where
            E: de::Error,
        {
            Ok(Vec::new())
        }

        fn visit_none<E>(self) -> Result<Self::Value, E>
        where
            E: de::Error,
        {
            Ok(Vec::new())
        }

        fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
        where
            A: SeqAccess<'de>,
        {
            Deserialize::deserialize(de::value::SeqAccessDeserializer::new(seq))
        }

        fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
        where
            A: MapAccess<'de>,
        {
            Ok(vec![Deserialize::deserialize(
                de::value::MapAccessDeserializer::new(map),
            )?])
        }
    }

    deserializer.deserialize_any(MaybeVecVisitor(std::marker::PhantomData))
}

pub fn duration_from_millis<'de, D>(
    deserializer: D,
) -> Result<Duration, D::Error>
where
    D: Deserializer<'de>,
{
    let millis = u64::deserialize(deserializer)?;
    Ok(Duration::from_millis(millis))
}

pub fn opt_duration_from_millis<'de, D>(
    deserializer: D,
) -> Result<Option<Duration>, D::Error>
where
    D: Deserializer<'de>,
{
    let millis = Option::<u64>::deserialize(deserializer)?;
    Ok(millis.map(Duration::from_millis))
}

pub fn duration_to_secs<S>(
    duration: &Duration,
    serializer: S,
) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    serializer.serialize_u64(duration.as_secs())
}