1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use crate::datum::time::Time;
use crate::{pg_sys, FromDatum, IntoDatum, PgBox};
use std::ops::{Deref, DerefMut};
#[derive(Debug)]
pub struct TimeWithTimeZone(Time);
impl FromDatum for TimeWithTimeZone {
#[inline]
unsafe fn from_datum(datum: usize, is_null: bool, typoid: u32) -> Option<TimeWithTimeZone> {
if is_null {
None
} else {
let timetz = PgBox::from_pg(datum as *mut pg_sys::TimeTzADT);
let mut time = Time::from_datum(timetz.time as pg_sys::Datum, false, typoid)
.expect("failed to convert TimeWithTimeZone");
time.0 += time::Duration::seconds(timetz.zone as i64);
Some(TimeWithTimeZone(time))
}
}
}
impl IntoDatum for TimeWithTimeZone {
#[inline]
fn into_datum(self) -> Option<pg_sys::Datum> {
let mut timetz = PgBox::<pg_sys::TimeTzADT>::alloc();
timetz.zone = 0;
timetz.time = self
.0
.into_datum()
.expect("failed to convert timetz into datum") as i64;
Some(timetz.into_pg() as pg_sys::Datum)
}
fn type_oid() -> u32 {
pg_sys::TIMETZOID
}
}
impl TimeWithTimeZone {
pub fn new(mut time: time::Time, at_tz_offset: time::UtcOffset) -> Self {
time -= time::Duration::seconds(at_tz_offset.as_seconds() as i64);
TimeWithTimeZone(Time(time))
}
}
impl Deref for TimeWithTimeZone {
type Target = time::Time;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for TimeWithTimeZone {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl serde::Serialize for TimeWithTimeZone {
fn serialize<S>(
&self,
serializer: S,
) -> std::result::Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
where
S: serde::Serializer,
{
if self.millisecond() > 0 {
serializer.serialize_str(&self.format(&format!("%H:%M:%S.{}-00", self.millisecond())))
} else {
serializer.serialize_str(&self.format("%H:%M:%S-00"))
}
}
}