mmd-anim-format 0.1.8

MMD format parser and exporter for mmd-anim
Documentation
use std::fmt;

use serde::{
    Deserialize, Deserializer, Serialize, Serializer,
    de::{self, SeqAccess, Visitor},
    ser::SerializeSeq,
};

const NAN_TOKEN: &str = "NaN";
const INFINITY_TOKEN: &str = "Infinity";
const NEG_INFINITY_TOKEN: &str = "-Infinity";

#[derive(Clone, Copy)]
struct JsonF32(f32);

impl Serialize for JsonF32 {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        if self.0.is_nan() {
            serializer.serialize_str(NAN_TOKEN)
        } else if self.0 == f32::INFINITY {
            serializer.serialize_str(INFINITY_TOKEN)
        } else if self.0 == f32::NEG_INFINITY {
            serializer.serialize_str(NEG_INFINITY_TOKEN)
        } else {
            serializer.serialize_f32(self.0)
        }
    }
}

impl<'de> Deserialize<'de> for JsonF32 {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(JsonF32Visitor)
    }
}

struct JsonF32Visitor;

impl<'de> Visitor<'de> for JsonF32Visitor {
    type Value = JsonF32;

    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        formatter.write_str("a finite f32 number or one of \"NaN\", \"Infinity\", \"-Infinity\"")
    }

    fn visit_f32<E>(self, value: f32) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(JsonF32(value))
    }

    fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(JsonF32(value as f32))
    }

    fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(JsonF32(value as f32))
    }

    fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(JsonF32(value as f32))
    }

    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        parse_json_f32(value).map(JsonF32)
    }

    fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        self.visit_str(&value)
    }
}

fn parse_json_f32<E>(value: &str) -> Result<f32, E>
where
    E: de::Error,
{
    match value {
        NAN_TOKEN => Ok(f32::NAN),
        INFINITY_TOKEN => Ok(f32::INFINITY),
        NEG_INFINITY_TOKEN => Ok(f32::NEG_INFINITY),
        _ => {
            let parsed = value
                .parse::<f32>()
                .map_err(|_| E::custom(format!("invalid f32 string {value:?}")))?;
            if parsed.is_finite() {
                Ok(parsed)
            } else {
                Err(E::custom(format!(
                    "non-finite f32 string {value:?} must use one of \"NaN\", \"Infinity\", \"-Infinity\""
                )))
            }
        }
    }
}

pub fn serialize<S>(value: &f32, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    JsonF32(*value).serialize(serializer)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<f32, D::Error>
where
    D: Deserializer<'de>,
{
    JsonF32::deserialize(deserializer).map(|value| value.0)
}

fn serialize_slice<S>(values: &[f32], serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    let mut seq = serializer.serialize_seq(Some(values.len()))?;
    for value in values {
        seq.serialize_element(&JsonF32(*value))?;
    }
    seq.end()
}

fn deserialize_vec<'de, D>(deserializer: D) -> Result<Vec<f32>, D::Error>
where
    D: Deserializer<'de>,
{
    Vec::<JsonF32>::deserialize(deserializer)
        .map(|values| values.into_iter().map(|value| value.0).collect())
}

fn next_array_value<'de, A>(seq: &mut A, index: usize, len: usize) -> Result<f32, A::Error>
where
    A: SeqAccess<'de>,
{
    seq.next_element::<JsonF32>()?
        .map(|value| value.0)
        .ok_or_else(|| de::Error::invalid_length(index, &ArrayLength { len }))
}

struct ArrayLength {
    len: usize,
}

impl de::Expected for ArrayLength {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(formatter, "an array of {} f32 values", self.len)
    }
}

pub mod vec_f32 {
    use super::*;

    pub fn serialize<S>(values: &[f32], serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serialize_slice(values, serializer)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<f32>, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserialize_vec(deserializer)
    }
}

pub mod nested_vec {
    use super::*;

    struct JsonF32Slice<'a>(&'a [f32]);

    impl Serialize for JsonF32Slice<'_> {
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: Serializer,
        {
            serialize_slice(self.0, serializer)
        }
    }

    pub fn serialize<S>(values: &[Vec<f32>], serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut seq = serializer.serialize_seq(Some(values.len()))?;
        for values in values {
            seq.serialize_element(&JsonF32Slice(values))?;
        }
        seq.end()
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Vec<f32>>, D::Error>
    where
        D: Deserializer<'de>,
    {
        Vec::<Vec<JsonF32>>::deserialize(deserializer).map(|values| {
            values
                .into_iter()
                .map(|values| values.into_iter().map(|value| value.0).collect())
                .collect()
        })
    }
}

pub mod array3 {
    use super::*;

    pub fn serialize<S>(values: &[f32; 3], serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serialize_slice(values, serializer)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<[f32; 3], D::Error>
    where
        D: Deserializer<'de>,
    {
        struct Array3Visitor;

        impl<'de> Visitor<'de> for Array3Visitor {
            type Value = [f32; 3];

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                formatter.write_str("an array of 3 f32 values")
            }

            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
            where
                A: SeqAccess<'de>,
            {
                Ok([
                    next_array_value(&mut seq, 0, 3)?,
                    next_array_value(&mut seq, 1, 3)?,
                    next_array_value(&mut seq, 2, 3)?,
                ])
            }
        }

        deserializer.deserialize_seq(Array3Visitor)
    }
}

pub mod array4 {
    use super::*;

    pub fn serialize<S>(values: &[f32; 4], serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serialize_slice(values, serializer)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<[f32; 4], D::Error>
    where
        D: Deserializer<'de>,
    {
        struct Array4Visitor;

        impl<'de> Visitor<'de> for Array4Visitor {
            type Value = [f32; 4];

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                formatter.write_str("an array of 4 f32 values")
            }

            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
            where
                A: SeqAccess<'de>,
            {
                Ok([
                    next_array_value(&mut seq, 0, 4)?,
                    next_array_value(&mut seq, 1, 4)?,
                    next_array_value(&mut seq, 2, 4)?,
                    next_array_value(&mut seq, 3, 4)?,
                ])
            }
        }

        deserializer.deserialize_seq(Array4Visitor)
    }
}

pub mod option_array3 {
    use super::*;

    pub fn serialize<S>(values: &Option<[f32; 3]>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        struct JsonF32Array3<'a>(&'a [f32; 3]);

        impl Serialize for JsonF32Array3<'_> {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where
                S: Serializer,
            {
                serialize_slice(self.0, serializer)
            }
        }

        match values {
            Some(values) => serializer.serialize_some(&JsonF32Array3(values)),
            None => serializer.serialize_none(),
        }
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<[f32; 3]>, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct OptionArray3Visitor;

        impl<'de> Visitor<'de> for OptionArray3Visitor {
            type Value = Option<[f32; 3]>;

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                formatter.write_str("null or an array of 3 f32 values")
            }

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

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

            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where
                D: Deserializer<'de>,
            {
                super::array3::deserialize(deserializer).map(Some)
            }
        }

        deserializer.deserialize_option(OptionArray3Visitor)
    }
}