ccdata_api/
schemas.rs

1pub mod min_api;
2pub mod data_api;
3
4
5use serde::{Deserialize, Deserializer};
6
7
8#[derive(Debug, PartialEq)]
9/// Custom response type that may use different types for the same value.
10pub enum StringOrInt {
11    String(String),
12    Int64(i64),
13    UInt64(u64),
14}
15
16impl<'de> Deserialize<'de> for StringOrInt {
17    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
18        struct Visitor;
19
20        impl<'de> serde::de::Visitor<'de> for Visitor {
21            type Value = StringOrInt;
22
23            fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
24                write!(f, "a String, i64 or u64")
25            }
26
27            fn visit_string<E: serde::de::Error>(self, s: String) -> Result<Self::Value, E> {
28                Ok(StringOrInt::String(s))
29            }
30
31            fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<Self::Value, E> {
32                Ok(StringOrInt::Int64(v))
33            }
34
35            fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Self::Value, E> {
36                Ok(StringOrInt::UInt64(v))
37            }
38        }
39
40        deserializer.deserialize_any(Visitor)
41    }
42}
43
44
45// Min-API Wrappers
46
47
48#[derive(Deserialize, Debug)]
49pub struct CCCallsMade {
50    pub second: i32,
51    pub minute: i32,
52    pub hour: i32,
53    pub day: i32,
54    pub month: i32,
55    pub total_calls: i32,
56}
57
58#[derive(Deserialize, Debug)]
59pub struct CCMaxCalls {
60    pub second: i32,
61    pub minute: i32,
62    pub hour: i32,
63    pub day: i32,
64    pub month: i32,
65}
66
67#[derive(Deserialize, Debug)]
68pub struct CCRateLimit {
69    pub calls_made: Option<CCCallsMade>,
70    pub max_calls: Option<CCMaxCalls>,
71}
72
73#[derive(Deserialize, Debug)]
74pub struct CCMinWrapper<T> {
75    #[serde(rename = "Aggregated")]
76    pub aggregated: Option<bool>,
77    #[serde(rename = "TimeFrom")]
78    pub time_from: Option<i64>,
79    #[serde(rename = "TimeTo")]
80    pub time_to: Option<i64>,
81    #[serde(rename = "Data")]
82    pub data: Option<T>,
83}
84
85#[derive(Deserialize, Debug)]
86pub struct CCMinResponse<T> {
87    #[serde(rename = "Response")]
88    pub response: String,
89    #[serde(rename = "Message")]
90    pub message: String,
91    #[serde(rename = "HasWarning")]
92    pub has_warning: bool,
93    #[serde(rename = "Type")]
94    pub type_: i32,
95    #[serde(rename = "Data")]
96    pub data: Option<T>,
97    #[serde(rename = "RateLimit")]
98    pub rate_limit: Option<CCRateLimit>,
99}
100
101
102// Data-API Wrappers
103
104
105#[derive(Deserialize, Debug)]
106pub struct CCErrorOtherInfo {
107    /// The parameter that is responsible for the error.
108    pub param: Option<String>,
109    /// The values responsible for the error.
110    pub values: Option<Vec<StringOrInt>>,
111    // Instrument specific information
112    /// Status of the instrument.
113    pub instrument_status: Option<String>,
114    /// First available timestamp.
115    pub first: Option<i64>,
116    /// Last available timestamp.
117    pub last: Option<i64>,
118    /// Earliest bucket timestamp.
119    pub first_bucket: Option<i64>,
120}
121
122#[derive(Deserialize, Debug)]
123/// This object provides detailed information about an error encountered while processing the request. It includes an error code, a message explaining the error,
124/// and additional context about the parameters or values that caused the issue. This helps clients identify and resolve issues with their requests.
125pub struct CCError {
126    #[serde(rename = "type")]
127    /// A public facing error type. If you want to treat a specific error use the type.
128    pub type_: i32,
129    /// A message describing the error.
130    pub message: String,
131    pub other_info: Option<CCErrorOtherInfo>,
132}
133
134#[derive(Deserialize, Debug)]
135pub struct CCDataResponse<T> {
136    #[serde(rename = "Data")]
137    pub data: Option<T>,
138    #[serde(rename = "Err")]
139    /// This object provides detailed information about an error encountered while processing the request. It includes an error code,
140    /// a message explaining the error, and additional context about the parameters or values that caused the issue.
141    /// This helps clients identify and resolve issues with their requests.
142    pub error: Option<CCError>,
143}
144
145
146#[cfg(test)]
147mod tests {
148
149    #[test]
150    fn unit_test_nullable_field() -> () {
151        use serde_json;
152        use crate::schemas;
153        let d: String = String::from("{\"Data\":{}, \"Err\":{\"type\": 23, \"message\": \"hello\", \"other_info\":null}}");
154        let response: schemas::CCDataResponse<String> = serde_json::from_str(&d.to_string().replace("{}", "null")).unwrap();
155        assert_eq!(response.data, None);
156    }
157}