godot_binary_serialization/encoder/
float.rs

1use core::f32;
2
3use byteorder::{ByteOrder, LittleEndian};
4
5use crate::types::{
6    primitive::GodotFloat, variant::GodotVariant, SerializeFlag, GodotTypeIndex, TYPE_PADDING,
7};
8
9use super::Encoder;
10
11impl Encoder {
12    /// Encodes a Godot float into bytes. A Godot float will be encoded into its respective
13    /// sizes based on the float. If the byte length of the float is over the 
14    /// [32 bit size](GodotFloat::BIT_32_SIZE)
15    pub fn encode_float(float: &GodotFloat) -> anyhow::Result<Vec<u8>> {
16        if float.byte_length() > TYPE_PADDING as usize + GodotFloat::BIT_32_SIZE {
17            return Ok(Self::encode_f64(float.value));
18        }
19
20        Ok(Self::encode_f32(float.value as f32))
21    }
22
23    /// Encodes a 32 bit float into bytes
24    pub fn encode_f32(i: f32) -> Vec<u8> {
25        let bytes: &mut [u8] = &mut [0; 8];
26        LittleEndian::write_i16(&mut bytes[0..2], GodotTypeIndex::Float as i16);
27        LittleEndian::write_i16(&mut bytes[2..4], SerializeFlag::None as i16);
28        LittleEndian::write_f32(&mut bytes[4..8], i);
29
30        bytes.to_vec()
31    }
32
33    /// Encodes a 64 bit float into bytes
34    pub fn encode_f64(i: f64) -> Vec<u8> {
35        let bytes: &mut [u8] = &mut [0; 12];
36        LittleEndian::write_i16(&mut bytes[0..2], GodotTypeIndex::Float as i16);
37        LittleEndian::write_i16(&mut bytes[2..4], SerializeFlag::Bit64 as i16);
38        LittleEndian::write_f64(&mut bytes[4..12], i);
39
40        bytes.to_vec()
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use crate::{encoder::Encoder, types::primitive::GodotFloat};
47
48    #[test]
49    fn encode_f64() {
50        let expected_bytes = [3, 0, 1, 0, 174, 230, 149, 231, 52, 245, 226, 63].to_vec();
51        let value = GodotFloat::new_from_f64(0.59243245345643);
52        let bytes = Encoder::encode_float(&value).unwrap();
53
54        assert_eq!(
55            expected_bytes, bytes,
56            "Expected {:?} but got {:?}",
57            expected_bytes, bytes
58        );
59    }
60}