Skip to main content

voidmc_codec/primitives/
floats.rs

1use crate::{Decode, DecodeError, Encode};
2
3impl Encode for f32 {
4    fn encode(&self, buf: &mut Vec<u8>) {
5        buf.extend_from_slice(&self.to_be_bytes());
6    }
7}
8
9impl Decode for f32 {
10    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
11        if buf.len() < 4 {
12            return Err(DecodeError::UnexpectedEof);
13        }
14
15        let (bytes, rest) = buf.split_at(4);
16        *buf = rest;
17
18        let mut array = [0u8; 4];
19        array.copy_from_slice(bytes);
20        Ok(f32::from_be_bytes(array))
21    }
22}
23
24impl Encode for f64 {
25    fn encode(&self, buf: &mut Vec<u8>) {
26        buf.extend_from_slice(&self.to_be_bytes());
27    }
28}
29
30impl Decode for f64 {
31    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
32        if buf.len() < 8 {
33            return Err(DecodeError::UnexpectedEof);
34        }
35
36        let (bytes, rest) = buf.split_at(8);
37        *buf = rest;
38
39        let mut array = [0u8; 8];
40        array.copy_from_slice(bytes);
41        Ok(f64::from_be_bytes(array))
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn test_f32_roundtrip() {
51        let value = std::f32::consts::PI;
52        let mut buf = Vec::new();
53        value.encode(&mut buf);
54
55        let mut slice = buf.as_slice();
56        let decoded = f32::decode(&mut slice).unwrap();
57        assert_eq!(decoded, value);
58    }
59
60    #[test]
61    fn test_f64_roundtrip() {
62        let value = std::f64::consts::PI;
63        let mut buf = Vec::new();
64        value.encode(&mut buf);
65
66        let mut slice = buf.as_slice();
67        let decoded = f64::decode(&mut slice).unwrap();
68        assert_eq!(decoded, value);
69    }
70
71    #[test]
72    fn test_f32_exact_bytes_zero() {
73        let mut buf = Vec::new();
74        (0.0f32).encode(&mut buf);
75        assert_eq!(buf, vec![0x00, 0x00, 0x00, 0x00]);
76    }
77
78    #[test]
79    fn test_f32_exact_bytes_one() {
80        let mut buf = Vec::new();
81        (1.0f32).encode(&mut buf);
82        assert_eq!(buf, vec![0x3F, 0x80, 0x00, 0x00]);
83    }
84
85    #[test]
86    fn test_f32_exact_bytes_negative_one() {
87        let mut buf = Vec::new();
88        (-1.0f32).encode(&mut buf);
89        assert_eq!(buf, vec![0xBF, 0x80, 0x00, 0x00]);
90    }
91
92    #[test]
93    fn test_f32_exact_bytes_pi() {
94        let mut buf = Vec::new();
95        (std::f32::consts::PI).encode(&mut buf);
96        let pi_bytes = std::f32::consts::PI.to_be_bytes();
97        assert_eq!(buf, pi_bytes.to_vec());
98    }
99
100    #[test]
101    fn test_f32_infinity() {
102        let mut buf = Vec::new();
103        (f32::INFINITY).encode(&mut buf);
104        assert_eq!(buf, vec![0x7F, 0x80, 0x00, 0x00]);
105    }
106
107    #[test]
108    fn test_f32_neg_infinity() {
109        let mut buf = Vec::new();
110        (f32::NEG_INFINITY).encode(&mut buf);
111        assert_eq!(buf, vec![0xFF, 0x80, 0x00, 0x00]);
112    }
113
114    #[test]
115    fn test_f64_exact_bytes_zero() {
116        let mut buf = Vec::new();
117        (0.0f64).encode(&mut buf);
118        assert_eq!(buf, vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
119    }
120
121    #[test]
122    fn test_f64_exact_bytes_one() {
123        let mut buf = Vec::new();
124        (1.0f64).encode(&mut buf);
125        assert_eq!(buf, vec![0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
126    }
127
128    #[test]
129    fn test_f64_exact_bytes_negative_one() {
130        let mut buf = Vec::new();
131        (-1.0f64).encode(&mut buf);
132        assert_eq!(buf, vec![0xBF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
133    }
134
135    #[test]
136    fn test_f64_exact_bytes_pi() {
137        let mut buf = Vec::new();
138        (std::f64::consts::PI).encode(&mut buf);
139        let pi_bytes = std::f64::consts::PI.to_be_bytes();
140        assert_eq!(buf, pi_bytes.to_vec());
141    }
142
143    #[test]
144    fn test_f64_infinity() {
145        let mut buf = Vec::new();
146        (f64::INFINITY).encode(&mut buf);
147        assert_eq!(buf, vec![0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
148    }
149
150    #[test]
151    fn test_f64_neg_infinity() {
152        let mut buf = Vec::new();
153        (f64::NEG_INFINITY).encode(&mut buf);
154        assert_eq!(buf, vec![0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
155    }
156
157    #[test]
158    fn test_f32_small_positive() {
159        let value = 0.5f32;
160        let mut buf = Vec::new();
161        value.encode(&mut buf);
162        assert_eq!(buf, vec![0x3F, 0x00, 0x00, 0x00]);
163    }
164
165    #[test]
166    fn test_f64_small_positive() {
167        let value = 0.5f64;
168        let mut buf = Vec::new();
169        value.encode(&mut buf);
170        assert_eq!(buf, vec![0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
171    }
172}