datatypes/
time.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use common_time::time::Time;
16use common_time::timestamp::TimeUnit;
17use paste::paste;
18use serde::{Deserialize, Serialize};
19
20use crate::prelude::{Scalar, Value, ValueRef};
21use crate::scalars::ScalarRef;
22use crate::types::{
23    TimeMicrosecondType, TimeMillisecondType, TimeNanosecondType, TimeSecondType, WrapperType,
24};
25use crate::vectors::{
26    TimeMicrosecondVector, TimeMillisecondVector, TimeNanosecondVector, TimeSecondVector,
27};
28
29macro_rules! define_time_with_unit {
30    ($unit: ident, $native_ty: ty) => {
31        paste! {
32            #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
33            pub struct [<Time $unit>](pub Time);
34
35            impl [<Time $unit>] {
36                pub fn new(val: i64) -> Self {
37                    Self(Time::new(val, TimeUnit::$unit))
38                }
39            }
40
41            impl Default for [<Time $unit>] {
42                fn default() -> Self {
43                    Self::new(0)
44                }
45            }
46
47            impl From<[<Time $unit>]> for Value {
48                fn from(t: [<Time $unit>]) -> Value {
49                    Value::Time(t.0)
50                }
51            }
52
53            impl From<[<Time $unit>]> for serde_json::Value {
54                fn from(t: [<Time $unit>]) -> Self {
55                    t.0.into()
56                }
57            }
58
59            impl From<[<Time $unit>]> for ValueRef<'static> {
60                fn from(t: [<Time $unit>]) -> Self {
61                    ValueRef::Time(t.0)
62                }
63            }
64
65            impl Scalar for [<Time $unit>] {
66                type VectorType = [<Time $unit Vector>];
67                type RefType<'a> = [<Time $unit>];
68
69                fn as_scalar_ref(&self) -> Self::RefType<'_> {
70                    *self
71                }
72
73                fn upcast_gat<'short, 'long: 'short>(
74                    long: Self::RefType<'long>,
75                ) -> Self::RefType<'short> {
76                    long
77                }
78            }
79
80            impl<'a> ScalarRef<'a> for [<Time $unit>] {
81                type ScalarType = [<Time $unit>];
82
83                fn to_owned_scalar(&self) -> Self::ScalarType {
84                    *self
85                }
86            }
87
88            impl WrapperType for [<Time $unit>] {
89                type LogicalType = [<Time $unit Type>];
90                type Native = $native_ty;
91
92                fn from_native(value: Self::Native) -> Self {
93                    Self::new(value.into())
94                }
95
96                fn into_native(self) -> Self::Native {
97                    self.0.into()
98                }
99            }
100
101            impl From<i64> for [<Time $unit>] {
102                fn from(val: i64) -> Self {
103                    [<Time $unit>]::from_native(val as $native_ty)
104                }
105            }
106
107            impl From<[<Time $unit>]> for i64 {
108                fn from(val: [<Time $unit>]) -> Self {
109                    val.0.value()
110                }
111            }
112
113            impl TryFrom<Value> for Option<[<Time $unit>]> {
114                type Error = $crate::error::Error;
115
116                #[inline]
117                fn try_from(from: Value) -> std::result::Result<Self, Self::Error> {
118                    match from {
119                        Value::Time(v) if *v.unit() == TimeUnit::$unit => {
120                            Ok(Some([<Time $unit>](v)))
121                        },
122                        Value::Null => Ok(None),
123                        _ => $crate::error::TryFromValueSnafu {
124                            reason: format!("{:?} is not a {}", from, stringify!([<Time $unit>])),
125                        }
126                        .fail(),
127                    }
128                }
129            }
130        }
131    };
132}
133
134define_time_with_unit!(Second, i32);
135define_time_with_unit!(Millisecond, i32);
136define_time_with_unit!(Microsecond, i64);
137define_time_with_unit!(Nanosecond, i64);
138
139#[cfg(test)]
140mod tests {
141    use common_time::timezone::set_default_timezone;
142
143    use super::*;
144
145    #[test]
146    fn test_to_serde_json_value() {
147        set_default_timezone(Some("Asia/Shanghai")).unwrap();
148        let time = TimeSecond::new(123);
149        let val = serde_json::Value::from(time);
150        match val {
151            serde_json::Value::String(s) => {
152                assert_eq!("08:02:03+0800", s);
153            }
154            _ => unreachable!(),
155        }
156    }
157
158    #[test]
159    fn test_time_scalar() {
160        let time = TimeSecond::new(123);
161        assert_eq!(time, time.as_scalar_ref());
162        assert_eq!(time, time.to_owned_scalar());
163        assert_eq!(123, time.into_native());
164        let time = TimeMillisecond::new(123);
165        assert_eq!(time, time.as_scalar_ref());
166        assert_eq!(time, time.to_owned_scalar());
167        assert_eq!(123, time.into_native());
168        let time = TimeMicrosecond::new(123);
169        assert_eq!(time, time.as_scalar_ref());
170        assert_eq!(time, time.to_owned_scalar());
171        assert_eq!(123, time.into_native());
172        let time = TimeNanosecond::new(123);
173        assert_eq!(time, time.as_scalar_ref());
174        assert_eq!(time, time.to_owned_scalar());
175        assert_eq!(123, time.into_native());
176    }
177}