badgeland 0.15.0

Fast badge generator for any purpose
Documentation
#[cfg(feature = "serde_de")]
use serde::{Deserialize, Serialize};
use std::{iter::FromIterator, num::ParseFloatError, str::FromStr, sync::Arc};

#[derive(Debug, PartialEq, Clone)]
pub struct BadgeData(pub Arc<[f32]>);

#[cfg(feature = "serde_de")]
impl Serialize for BadgeData {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        self.0.serialize(serializer)
    }
}

#[cfg(feature = "serde_de")]
impl<'de> Deserialize<'de> for BadgeData {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data: Vec<f32> = Vec::deserialize(deserializer)?;
        Ok(BadgeData(Arc::from(data.into_boxed_slice())))
    }
}

impl FromStr for BadgeData {
    type Err = ParseFloatError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        s.split(",")
            .map(|s| s.trim().parse::<f32>())
            .collect::<Result<Self, Self::Err>>()
    }
}

impl AsRef<[f32]> for BadgeData {
    fn as_ref(&self) -> &[f32] {
        &self.0[..]
    }
}

impl FromIterator<f32> for BadgeData {
    fn from_iter<I: IntoIterator<Item = f32>>(iter: I) -> Self {
        BadgeData(iter.into_iter().collect())
    }
}

#[cfg(test)]
mod tests {

    use super::BadgeData;

    #[test]
    fn data_from_string_fails() {
        let d = "not a number".parse::<BadgeData>();
        assert!(d.is_err());
        let d = "12,12,,12".parse::<BadgeData>();
        assert!(d.is_err());
    }

    #[test]
    fn data_from_string_parse_correct() {
        let d = "12,23, 23, 12".parse::<BadgeData>();
        assert!(d.is_ok());
        assert_eq!(d.unwrap().0, vec![12., 23., 23., 12.].into());
    }

    #[test]
    fn struct_collect_pass() {
        let d: BadgeData = vec![12, 32, 32, 12, 42]
            .into_iter()
            .map(|v| v as f32)
            .collect();
        assert_eq!(d, BadgeData(vec![12., 32., 32., 12., 42.].into()));
    }

    #[cfg(feature = "serde_de")]
    mod serde_tests {
        use super::BadgeData;
        use serde_test::{assert_de_tokens, assert_ser_tokens, Token};

        #[test]
        fn struct_serialize_pass() {
            let d = BadgeData(vec![12., 32., 32., 12., 42.].into());
            assert_ser_tokens(
                &d,
                &[
                    Token::Seq { len: Some(5) },
                    Token::F32(12.),
                    Token::F32(32.),
                    Token::F32(32.),
                    Token::F32(12.),
                    Token::F32(42.),
                    Token::SeqEnd,
                ],
            );
        }

        #[test]
        fn struct_deserialize_pass() {
            let d = BadgeData(vec![12., 32., 32., 12., 42.].into());
            assert_de_tokens(
                &d,
                &[
                    Token::Seq { len: Some(5) },
                    Token::F32(12.),
                    Token::F32(32.),
                    Token::F32(32.),
                    Token::F32(12.),
                    Token::F32(42.),
                    Token::SeqEnd,
                ],
            );
        }
    }
}