sea_query/value/
with_jiff.rs

1use super::*;
2use jiff::{Timestamp, Zoned, civil};
3
4type_to_value!(civil::Date, JiffDate, Date);
5type_to_value!(civil::Time, JiffTime, Time);
6type_to_box_value!(civil::DateTime, JiffDateTime, DateTime);
7type_to_box_value!(Timestamp, JiffTimestamp, Timestamp);
8type_to_box_value!(Zoned, JiffZoned, TimestampWithTimeZone);
9
10impl DateLikeValue for civil::Date {}
11impl TimeLikeValue for civil::Time {}
12impl DateTimeLikeValue for civil::DateTime {}
13impl DateTimeLikeValue for Timestamp {}
14impl DateTimeLikeValue for Zoned {}
15
16impl Value {
17    #[inline]
18    pub fn jiff_date<T: Into<Option<civil::Date>>>(v: T) -> Value {
19        Value::JiffDate(v.into())
20    }
21
22    #[inline]
23    pub fn jiff_time<T: Into<Option<civil::Time>>>(v: T) -> Value {
24        Value::JiffTime(v.into())
25    }
26
27    #[inline]
28    pub fn jiff_date_time<T: Into<Option<civil::DateTime>>>(v: T) -> Value {
29        Value::JiffDateTime(v.into().map(Into::into))
30    }
31
32    #[inline]
33    pub fn jiff_timestamp<T: Into<Option<Timestamp>>>(v: T) -> Value {
34        Value::JiffTimestamp(v.into().map(Into::into))
35    }
36
37    #[inline]
38    pub fn jiff_zoned<T: Into<Option<Zoned>>>(v: T) -> Value {
39        Value::JiffZoned(v.into().map(Into::into))
40    }
41}
42
43impl Value {
44    pub fn is_jiff_date(&self) -> bool {
45        matches!(self, Self::JiffDate(_))
46    }
47
48    pub fn is_jiff_time(&self) -> bool {
49        matches!(self, Self::JiffTime(_))
50    }
51
52    pub fn is_jiff_date_time(&self) -> bool {
53        matches!(self, Self::JiffDateTime(_))
54    }
55
56    pub fn is_jiff_timestamp(&self) -> bool {
57        matches!(self, Self::JiffTimestamp(_))
58    }
59
60    pub fn is_jiff_zoned(&self) -> bool {
61        matches!(self, Self::JiffZoned(_))
62    }
63
64    pub fn as_ref_jiff_date(&self) -> Option<&civil::Date> {
65        match self {
66            Self::JiffDate(v) => v.as_ref(),
67            _ => panic!("not Value::JiffDate"),
68        }
69    }
70
71    pub fn as_ref_jiff_time(&self) -> Option<&civil::Time> {
72        match self {
73            Self::JiffTime(v) => v.as_ref(),
74            _ => panic!("not Value::JiffTime"),
75        }
76    }
77
78    pub fn as_ref_jiff_date_time(&self) -> Option<&civil::DateTime> {
79        match self {
80            Self::JiffDateTime(v) => v.as_deref(),
81            _ => panic!("not Value::JiffDateTime"),
82        }
83    }
84
85    pub fn as_ref_jiff_timestamp(&self) -> Option<&Timestamp> {
86        match self {
87            Self::JiffTimestamp(v) => v.as_deref(),
88            _ => panic!("not Value::JiffTimestamp"),
89        }
90    }
91
92    pub fn as_ref_jiff_zoned(&self) -> Option<&Zoned> {
93        match self {
94            Self::JiffZoned(v) => v.as_deref(),
95            _ => panic!("not Value::JiffZoned"),
96        }
97    }
98}
99
100pub(crate) const JIFF_DATE_TIME_FMT_STR: &str = "%Y-%m-%d %H:%M:%S%.6f";
101pub(crate) const JIFF_TIMESTAMP_FMT_STR: &str = "%Y-%m-%d %H:%M:%S%.6f";
102pub(crate) const JIFF_ZONE_FMT_STR: &str = "%Y-%m-%d %H:%M:%S%.6f %:z";
103
104impl Value {
105    #[cfg(test)]
106    pub(crate) fn jiff_value_to_string(&self) -> Option<String> {
107        match self {
108            Self::JiffDate(v) => v.as_ref().map(|v| v.to_string()),
109            Self::JiffTime(v) => v.as_ref().map(|v| v.to_string()),
110            Self::JiffDateTime(v) => v
111                .as_ref()
112                .map(|v| v.strftime(JIFF_DATE_TIME_FMT_STR).to_string()),
113            Self::JiffTimestamp(v) => v
114                .as_ref()
115                .map(|v| v.strftime(JIFF_TIMESTAMP_FMT_STR).to_string()),
116            Self::JiffZoned(v) => v
117                .as_ref()
118                .map(|v| v.strftime(JIFF_ZONE_FMT_STR).to_string()),
119            _ => panic!("not jiff Value"),
120        }
121    }
122}
123
124#[cfg(test)]
125mod tests {
126
127    use jiff::fmt::strtime;
128
129    #[test]
130    fn jiff_fmt() {
131        use super::*;
132        assert_eq!(
133            Value::jiff_date(jiff::civil::date(2020, 1, 1)).jiff_value_to_string(),
134            Some("2020-01-01".to_owned())
135        );
136        assert_eq!(
137            Value::jiff_time(jiff::civil::time(1, 2, 3, 123456 * 1000)).jiff_value_to_string(),
138            Some("01:02:03.123456".to_owned())
139        );
140        assert_eq!(
141            Value::jiff_date_time(jiff::civil::date(2020, 1, 1).at(1, 2, 3, 123456 * 1000))
142                .jiff_value_to_string(),
143            Some("2020-01-01 01:02:03.123456".to_owned())
144        );
145
146        assert_eq!(
147            Value::jiff_timestamp(jiff::Timestamp::constant(0, 123456 * 1000))
148                .jiff_value_to_string(),
149            Some("1970-01-01 00:00:00.123456".to_owned())
150        );
151
152        assert_eq!(
153            Value::jiff_zoned(
154                strtime::parse(JIFF_ZONE_FMT_STR, "1970-01-01 00:00:00.123456 +00:00")
155                    .unwrap()
156                    .to_zoned()
157                    .unwrap()
158            )
159            .jiff_value_to_string(),
160            Some("1970-01-01 00:00:00.123456 +00:00".to_owned())
161        );
162    }
163}