rbdc_pg/types/
float.rs

1use crate::arguments::PgArgumentBuffer;
2use crate::types::decode::Decode;
3use crate::types::encode::{Encode, IsNull};
4use crate::value::{PgValue, PgValueFormat};
5use byteorder::{BigEndian, ByteOrder};
6use rbdc::Error;
7
8impl Decode for f64 {
9    fn decode(value: PgValue) -> Result<Self, Error> {
10        Ok(match value.format() {
11            PgValueFormat::Binary => BigEndian::read_f64(value.as_bytes()?),
12            PgValueFormat::Text => value.as_str()?.parse()?,
13        })
14    }
15}
16
17impl Decode for f32 {
18    fn decode(value: PgValue) -> Result<Self, Error> {
19        Ok(match value.format() {
20            PgValueFormat::Binary => {
21                let bytes = value.as_bytes()?;
22                if bytes.len() == 8 {
23                    BigEndian::read_f64(bytes) as f32
24                } else if bytes.len() == 4 {
25                    BigEndian::read_f32(bytes)
26                } else {
27                    return Err(Error::from("error f32 bytes len"));
28                }
29            }
30            PgValueFormat::Text => value.as_str()?.parse()?,
31        })
32    }
33}
34
35impl Encode for f64 {
36    fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
37        buf.extend(&self.to_be_bytes());
38
39        Ok(IsNull::No)
40    }
41}
42
43impl Encode for f32 {
44    fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
45        buf.extend(&self.to_be_bytes());
46
47        Ok(IsNull::No)
48    }
49}
50
51#[cfg(test)]
52mod test {
53    use crate::type_info::PgTypeInfo;
54    use crate::types::decode::Decode;
55    use crate::value::{PgValue, PgValueFormat};
56
57    #[test]
58    fn test_decode_f32() {
59        let bytes: [u8; 4] = 3_f32.to_be_bytes();
60        let r: f32 = Decode::decode(PgValue {
61            value: Some(bytes.to_vec()),
62            type_info: PgTypeInfo::FLOAT4,
63            format: PgValueFormat::Binary,
64            timezone_sec: None,
65        })
66        .unwrap();
67        assert_eq!(r, 3.0);
68    }
69
70    #[test]
71    fn test_decode_f32_by_f64() {
72        let bytes: [u8; 8] = 3_f64.to_be_bytes();
73        println!("bytes={:?}", bytes);
74        let r: f32 = Decode::decode(PgValue {
75            value: Some(bytes.to_vec()),
76            type_info: PgTypeInfo::FLOAT4,
77            format: PgValueFormat::Binary,
78            timezone_sec: None,
79        })
80        .unwrap();
81        assert_eq!(r, 3.0);
82    }
83}