voidmc_codec/primitives/
floats.rs1use 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}