rust_swf_fixed/
lib.rs

1use serde::{Serialize, Serializer, Deserialize, Deserializer};
2
3macro_rules! fixed_point_impl {
4  ($name:ident, $int_bits:expr, $frac_bits:expr, $epsilons_type:ty, $value_type:ty) => {
5    #[derive(PartialEq, Eq, Debug)]
6    pub struct $name {
7      epsilons: $epsilons_type,
8    }
9
10    impl $name {
11      pub fn from_epsilons(epsilons: $epsilons_type) -> $name {
12        $name {epsilons: epsilons}
13      }
14
15      pub fn from_value(value: $value_type) -> $name {
16        // TODO: Checked cast
17        let epsilons: $epsilons_type = (value * ((1 << $frac_bits) as $value_type)) as $epsilons_type;
18        $name {epsilons: epsilons}
19      }
20    }
21
22    impl Serialize for $name {
23      fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
24        self.epsilons.serialize(serializer)
25      }
26    }
27
28    impl<'a> Deserialize<'a> for $name {
29      fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'a> {
30        Ok($name::from_epsilons(<$epsilons_type>::deserialize(deserializer)?))
31      }
32    }
33  }
34}
35
36fixed_point_impl!(Sfixed8P8, 8, 8, i16, f32);
37fixed_point_impl!(Sfixed16P16, 16, 16, i32, f64);
38fixed_point_impl!(Ufixed8P8, 8, 8, u16, f32);
39fixed_point_impl!(Ufixed16P16, 16, 16, u32, f64);
40
41#[cfg(test)]
42mod tests {
43    use super::Sfixed16P16;
44    use super::Ufixed8P8;
45    use serde_json;
46
47    #[test]
48    fn test_eq() {
49        assert_eq!(Sfixed16P16::from_epsilons(3), Sfixed16P16::from_epsilons(3));
50    }
51
52    #[test]
53    fn test_json_serde_serialization() {
54        assert_eq!(serde_json::to_string(&Sfixed16P16::from_epsilons(3)).unwrap(), "3");
55    }
56
57    #[test]
58    fn test_json_serde_deserialization() {
59        assert_eq!(serde_json::from_str::<Sfixed16P16>("0").unwrap(), Sfixed16P16::from_epsilons(0));
60        assert_eq!(serde_json::from_str::<Sfixed16P16>("3").unwrap(), Sfixed16P16::from_epsilons(3));
61        assert_eq!(serde_json::from_str::<Sfixed16P16>("65536").unwrap(), Sfixed16P16::from_epsilons(65536));
62        assert_eq!(serde_json::from_str::<Sfixed16P16>("2147483647").unwrap(), Sfixed16P16::from_epsilons(2147483647));
63        assert_eq!(serde_json::from_str::<Sfixed16P16>("-2147483648").unwrap(), Sfixed16P16::from_epsilons(-2147483648));
64    }
65
66    #[test]
67    fn test_ufixed8p8() {
68        assert_eq!(serde_json::from_str::<Ufixed8P8>("6144").unwrap(), Ufixed8P8::from_value(24f32));
69    }
70}