rbdc_pg/types/
time.rs

1use rbdc::common::time::Time;
2use rbdc::Error;
3use std::str::FromStr;
4use std::time::Duration;
5
6use crate::arguments::PgArgumentBuffer;
7use crate::types::decode::Decode;
8use crate::types::encode::{Encode, IsNull};
9use crate::value::{PgValue, PgValueFormat};
10
11impl Decode for Time {
12    fn decode(value: PgValue) -> Result<Self, Error> {
13        match value.format() {
14            PgValueFormat::Binary => {
15                // TIME is encoded as the microseconds since midnight
16                let us = i64::decode(value)?;
17                //+microseconds
18                let t = fastdate::DateTime::from((
19                    fastdate::Date {
20                        day: 1,
21                        mon: 1,
22                        year: 2000,
23                    },
24                    fastdate::Time {
25                        nano: 0,
26                        sec: 0,
27                        minute: 0,
28                        hour: 0,
29                    },
30                ));
31                let t = {
32                    if us < 0 {
33                        t - Duration::from_micros(-us as u64)
34                    } else {
35                        t + Duration::from_micros(us as u64)
36                    }
37                };
38                Ok(Time(fastdate::Time {
39                    nano: t.nano(),
40                    sec: t.sec(),
41                    minute: t.minute(),
42                    hour: t.hour(),
43                }))
44            }
45            PgValueFormat::Text => Ok(Time(
46                fastdate::Time::from_str(value.as_str()?)
47                    .map_err(|e| Error::from(e.to_string()))?,
48            )),
49        }
50    }
51}
52
53impl Encode for Time {
54    fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
55        // TIME is encoded as the microseconds since midnight
56        // microseconds
57        let us = self.0.get_micro()
58            + self.0.hour as u32 * 60 * 60 * 1000000
59            + self.0.minute as u32 * 60 * 1000000
60            + self.0.sec as u32 * 1000000;
61        us.encode(buf)
62    }
63}