kiteconnect_async_wasm/models/common/enums/
interval.rs

1/*!
2Interval types for historical market data with dual string/integer serialization support.
3*/
4
5/// Interval types for historical data (supports both string and integer serialization)
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7#[repr(i8)]
8pub enum Interval {
9    Day = 0,
10    Minute = 1,
11    ThreeMinute = 2,
12    FiveMinute = 3,
13    TenMinute = 4,
14    FifteenMinute = 5,
15    ThirtyMinute = 6,
16    SixtyMinute = 7,
17}
18
19impl std::fmt::Display for Interval {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        match self {
22            Interval::Day => write!(f, "day"),
23            Interval::Minute => write!(f, "minute"),
24            Interval::ThreeMinute => write!(f, "3minute"),
25            Interval::FiveMinute => write!(f, "5minute"),
26            Interval::TenMinute => write!(f, "10minute"),
27            Interval::FifteenMinute => write!(f, "15minute"),
28            Interval::ThirtyMinute => write!(f, "30minute"),
29            Interval::SixtyMinute => write!(f, "60minute"),
30        }
31    }
32}
33
34// Custom serde implementation that supports both string and integer formats
35impl serde::Serialize for Interval {
36    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
37    where
38        S: serde::Serializer,
39    {
40        // Try to serialize as string first (for compatibility)
41        serializer.serialize_str(&self.to_string())
42    }
43}
44
45impl<'de> serde::Deserialize<'de> for Interval {
46    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
47    where
48        D: serde::Deserializer<'de>,
49    {
50        struct IntervalVisitor;
51
52        impl<'de> serde::de::Visitor<'de> for IntervalVisitor {
53            type Value = Interval;
54
55            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
56                formatter.write_str("a string or integer representing an interval")
57            }
58
59            fn visit_str<E>(self, value: &str) -> Result<Interval, E>
60            where
61                E: serde::de::Error,
62            {
63                match value {
64                    "minute" => Ok(Interval::Minute),
65                    "3minute" => Ok(Interval::ThreeMinute),
66                    "5minute" => Ok(Interval::FiveMinute),
67                    "10minute" => Ok(Interval::TenMinute),
68                    "15minute" => Ok(Interval::FifteenMinute),
69                    "30minute" => Ok(Interval::ThirtyMinute),
70                    "60minute" => Ok(Interval::SixtyMinute),
71                    "day" => Ok(Interval::Day),
72                    _ => Err(serde::de::Error::unknown_variant(
73                        value,
74                        &[
75                            "minute", "3minute", "5minute", "10minute", "15minute", "30minute",
76                            "60minute", "day",
77                        ],
78                    )),
79                }
80            }
81
82            fn visit_i8<E>(self, value: i8) -> Result<Interval, E>
83            where
84                E: serde::de::Error,
85            {
86                match value {
87                    0 => Ok(Interval::Day),
88                    1 => Ok(Interval::Minute),
89                    2 => Ok(Interval::ThreeMinute),
90                    3 => Ok(Interval::FiveMinute),
91                    4 => Ok(Interval::TenMinute),
92                    5 => Ok(Interval::FifteenMinute),
93                    6 => Ok(Interval::ThirtyMinute),
94                    7 => Ok(Interval::SixtyMinute),
95                    _ => Err(serde::de::Error::invalid_value(
96                        serde::de::Unexpected::Signed(value as i64),
97                        &"an integer between 0 and 7",
98                    )),
99                }
100            }
101
102            fn visit_u8<E>(self, value: u8) -> Result<Interval, E>
103            where
104                E: serde::de::Error,
105            {
106                self.visit_i8(value as i8)
107            }
108
109            fn visit_i32<E>(self, value: i32) -> Result<Interval, E>
110            where
111                E: serde::de::Error,
112            {
113                if (0..=7).contains(&value) {
114                    self.visit_i8(value as i8)
115                } else {
116                    Err(serde::de::Error::invalid_value(
117                        serde::de::Unexpected::Signed(value as i64),
118                        &"an integer between 0 and 7",
119                    ))
120                }
121            }
122
123            fn visit_u32<E>(self, value: u32) -> Result<Interval, E>
124            where
125                E: serde::de::Error,
126            {
127                if value <= 7 {
128                    self.visit_i8(value as i8)
129                } else {
130                    Err(serde::de::Error::invalid_value(
131                        serde::de::Unexpected::Unsigned(value as u64),
132                        &"an integer between 0 and 7",
133                    ))
134                }
135            }
136
137            fn visit_i64<E>(self, value: i64) -> Result<Interval, E>
138            where
139                E: serde::de::Error,
140            {
141                if (0..=7).contains(&value) {
142                    self.visit_i8(value as i8)
143                } else {
144                    Err(serde::de::Error::invalid_value(
145                        serde::de::Unexpected::Signed(value),
146                        &"an integer between 0 and 7",
147                    ))
148                }
149            }
150
151            fn visit_u64<E>(self, value: u64) -> Result<Interval, E>
152            where
153                E: serde::de::Error,
154            {
155                if value <= 7 {
156                    self.visit_i8(value as i8)
157                } else {
158                    Err(serde::de::Error::invalid_value(
159                        serde::de::Unexpected::Unsigned(value),
160                        &"an integer between 0 and 7",
161                    ))
162                }
163            }
164        }
165
166        deserializer.deserialize_any(IntervalVisitor)
167    }
168}
169
170impl Interval {
171    /// Get the integer representation of the interval
172    pub fn as_i8(self) -> i8 {
173        self as i8
174    }
175
176    /// Create an interval from its integer representation
177    pub fn from_i8(value: i8) -> Option<Self> {
178        match value {
179            0 => Some(Interval::Day),
180            1 => Some(Interval::Minute),
181            2 => Some(Interval::ThreeMinute),
182            3 => Some(Interval::FiveMinute),
183            4 => Some(Interval::TenMinute),
184            5 => Some(Interval::FifteenMinute),
185            6 => Some(Interval::ThirtyMinute),
186            7 => Some(Interval::SixtyMinute),
187            _ => None,
188        }
189    }
190
191    /// All available intervals
192    pub fn all() -> Vec<Self> {
193        vec![
194            Interval::Minute,
195            Interval::ThreeMinute,
196            Interval::FiveMinute,
197            Interval::TenMinute,
198            Interval::FifteenMinute,
199            Interval::ThirtyMinute,
200            Interval::SixtyMinute,
201            Interval::Day,
202        ]
203    }
204}