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 let us = i64::decode(value)?;
17 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 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}