datatypes/
duration.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::duration::Duration;
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    DurationMicrosecondType, DurationMillisecondType, DurationNanosecondType, DurationSecondType,
24    WrapperType,
25};
26use crate::vectors::{
27    DurationMicrosecondVector, DurationMillisecondVector, DurationNanosecondVector,
28    DurationSecondVector,
29};
30
31macro_rules! define_duration_with_unit {
32    ($unit: ident) => {
33        paste! {
34            #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
35            pub struct [<Duration $unit>](pub Duration);
36
37            impl [<Duration $unit>] {
38                pub fn new(val: i64) -> Self {
39                    Self(Duration::new(val, TimeUnit::$unit))
40                }
41            }
42
43            impl Default for [<Duration $unit>] {
44                fn default() -> Self {
45                    Self::new(0)
46                }
47            }
48
49            impl From<[<Duration $unit>]> for Value {
50                fn from(t: [<Duration $unit>]) -> Value {
51                    Value::Duration(t.0)
52                }
53            }
54
55            impl From<[<Duration $unit>]> for serde_json::Value {
56                fn from(t: [<Duration $unit>]) -> Self {
57                    t.0.into()
58                }
59            }
60
61            impl From<[<Duration $unit>]> for ValueRef<'static> {
62                fn from(t: [<Duration $unit>]) -> Self {
63                    ValueRef::Duration(t.0)
64                }
65            }
66
67            impl Scalar for [<Duration $unit>] {
68                type VectorType = [<Duration $unit Vector>];
69                type RefType<'a> = [<Duration $unit>];
70
71                fn as_scalar_ref(&self) -> Self::RefType<'_> {
72                    *self
73                }
74
75                fn upcast_gat<'short, 'long: 'short>(
76                    long: Self::RefType<'long>,
77                ) -> Self::RefType<'short> {
78                    long
79                }
80            }
81
82            impl<'a> ScalarRef<'a> for [<Duration $unit>] {
83                type ScalarType = [<Duration $unit>];
84
85                fn to_owned_scalar(&self) -> Self::ScalarType {
86                    *self
87                }
88            }
89
90            impl WrapperType for [<Duration $unit>] {
91                type LogicalType = [<Duration $unit Type>];
92                type Native = i64;
93
94                fn from_native(value: Self::Native) -> Self {
95                    Self::new(value)
96                }
97
98                fn into_native(self) -> Self::Native {
99                    self.0.into()
100                }
101            }
102
103            impl From<i64> for [<Duration $unit>] {
104                fn from(val: i64) -> Self {
105                    [<Duration $unit>]::from_native(val)
106                }
107            }
108
109            impl From<[<Duration $unit>]> for i64{
110                fn from(val: [<Duration $unit>]) -> Self {
111                    val.0.value()
112                }
113            }
114
115            impl TryFrom<Value> for Option<[<Duration $unit>]> {
116                type Error = $crate::error::Error;
117
118                #[inline]
119                fn try_from(from: Value) -> std::result::Result<Self, Self::Error> {
120                    match from {
121                        Value::Duration(v) if v.unit() == TimeUnit::$unit => {
122                            Ok(Some([<Duration $unit>](v)))
123                        },
124                        Value::Null => Ok(None),
125                        _ => $crate::error::TryFromValueSnafu {
126                            reason: format!("{:?} is not a {}", from, stringify!([<Duration $unit>])),
127                        }
128                        .fail(),
129                    }
130                }
131            }
132        }
133    };
134}
135
136define_duration_with_unit!(Second);
137define_duration_with_unit!(Millisecond);
138define_duration_with_unit!(Microsecond);
139define_duration_with_unit!(Nanosecond);
140
141#[cfg(test)]
142mod tests {
143    use super::*;
144
145    #[test]
146    fn test_duration_scalar() {
147        let d = DurationSecond::new(456);
148        assert_eq!(d, d.as_scalar_ref());
149        assert_eq!(d, d.to_owned_scalar());
150        let d = DurationMillisecond::new(456);
151        assert_eq!(d, d.as_scalar_ref());
152        assert_eq!(d, d.to_owned_scalar());
153        let d = DurationMicrosecond::new(456);
154        assert_eq!(d, d.as_scalar_ref());
155        assert_eq!(d, d.to_owned_scalar());
156        let d = DurationNanosecond::new(456);
157        assert_eq!(d, d.as_scalar_ref());
158        assert_eq!(d, d.to_owned_scalar());
159    }
160
161    #[test]
162    fn test_duration_to_native_type() {
163        let duration = DurationSecond::new(456);
164        let native: i64 = duration.into_native();
165        assert_eq!(native, 456);
166
167        let duration = DurationMillisecond::new(456);
168        let native: i64 = duration.into_native();
169        assert_eq!(native, 456);
170
171        let duration = DurationMicrosecond::new(456);
172        let native: i64 = duration.into_native();
173        assert_eq!(native, 456);
174
175        let duration = DurationNanosecond::new(456);
176        let native: i64 = duration.into_native();
177        assert_eq!(native, 456);
178    }
179}