ts_builder/
lib.rs

1use chrono::{DateTime, Duration, TimeZone, Utc};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3
4pub struct DateTimeRange(pub DateTime<Utc>, pub DateTime<Utc>, pub Duration);
5
6impl Iterator for DateTimeRange {
7    type Item = DateTime<Utc>;
8    fn next(&mut self) -> Option<Self::Item> {
9        if self.0 <= self.1 {
10            let next = self.0 + self.2;
11            Some(std::mem::replace(&mut self.0, next))
12        } else {
13            None
14        }
15    }
16}
17
18#[derive(Deserialize, Serialize, Debug)]
19pub struct TimestampBuilder {
20    // ts_fmt
21    // #[serde(with = "datetime_format", default = "default_start")]
22    #[serde(default = "default_start")]
23    pub start: DateTime<Utc>,
24    // #[serde(with = "datetime_format", default = "default_end")]
25    #[serde(default = "default_end")]
26    pub end: DateTime<Utc>,
27    #[serde(with = "duration_format", default = "default_interval")]
28    pub interval: Duration,
29    #[serde(default = "default_batch_size")]
30    pub batch_size: usize,
31}
32
33const FORMAT: &'static str = "%Y-%m-%d %H:%M";
34
35pub fn default_start() -> DateTime<Utc> {
36    Utc.datetime_from_str("2019-09-13 04:00", FORMAT).unwrap()
37}
38
39pub fn default_end() -> DateTime<Utc> {
40    Utc::now()
41}
42
43pub fn default_interval() -> Duration {
44    Duration::milliseconds(900000)
45}
46
47pub fn default_batch_size() -> usize {
48    499
49}
50
51pub mod duration_format {
52    use super::*;
53
54    pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
55    where
56        S: Serializer,
57    {
58        let s = serialize_duration(duration).map_err(serde::ser::Error::custom)?;
59        serializer.serialize_str(&s)
60    }
61
62    pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
63    where
64        D: Deserializer<'de>,
65    {
66        let s = String::deserialize(deserializer)?;
67        match s.as_str() {
68            "1m" => Ok(Duration::milliseconds(60000)),
69            "5m" => Ok(Duration::milliseconds(300000)),
70            "15m" => Ok(Duration::milliseconds(900000)),
71            "1h" => Ok(Duration::milliseconds(3600000)),
72            "4h" => Ok(Duration::milliseconds(14400000)),
73            "1d" => Ok(Duration::milliseconds(86400000)),
74            _ => Err(serde::de::Error::custom("unexpected time interval")),
75        }
76    }
77
78    pub fn serialize_duration(duration: &Duration) -> std::io::Result<&'static str> {
79        match duration.num_minutes() {
80            1 => Ok("1m"),
81            5 => Ok("5m"),
82            15 => Ok("15m"),
83            60 => Ok("1h"),
84            240 => Ok("4h"),
85            1440 => Ok("1d"),
86            _ => unimplemented!("not implemented interaval"),
87        }
88    }
89}