1use 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}