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}