pub mod min_api;
pub mod data_api;
use serde::{Serialize, Deserialize, Deserializer};
#[derive(Clone, Debug, PartialEq, Serialize)]
pub enum StringOrInt {
String(String),
Int64(i64),
UInt64(u64),
}
impl<'de> Deserialize<'de> for StringOrInt {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = StringOrInt;
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "a String, i64 or u64")
}
fn visit_string<E: serde::de::Error>(self, s: String) -> Result<Self::Value, E> {
Ok(StringOrInt::String(s))
}
fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<Self::Value, E> {
Ok(StringOrInt::Int64(v))
}
fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Self::Value, E> {
Ok(StringOrInt::UInt64(v))
}
}
deserializer.deserialize_any(Visitor)
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct CCCallsMade {
pub second: i32,
pub minute: i32,
pub hour: i32,
pub day: i32,
pub month: i32,
pub total_calls: i32,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct CCMaxCalls {
pub second: i32,
pub minute: i32,
pub hour: i32,
pub day: i32,
pub month: i32,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct CCRateLimit {
pub calls_made: Option<CCCallsMade>,
pub max_calls: Option<CCMaxCalls>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CCMinWrapper<T> {
#[serde(rename = "Aggregated")]
pub aggregated: Option<bool>,
#[serde(rename = "TimeFrom")]
pub time_from: Option<i64>,
#[serde(rename = "TimeTo")]
pub time_to: Option<i64>,
#[serde(rename = "Data")]
pub data: Option<T>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CCMinResponse<T> {
#[serde(rename = "Response")]
pub response: String,
#[serde(rename = "Message")]
pub message: String,
#[serde(rename = "HasWarning")]
pub has_warning: bool,
#[serde(rename = "Type")]
pub type_: i32,
#[serde(rename = "Data")]
pub data: Option<T>,
#[serde(rename = "RateLimit")]
pub rate_limit: Option<CCRateLimit>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CCErrorOtherInfo {
pub param: Option<String>,
pub values: Option<Vec<StringOrInt>>,
pub instrument_status: Option<String>,
pub first: Option<i64>,
pub last: Option<i64>,
pub first_bucket: Option<i64>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CCError {
#[serde(rename = "type")]
pub type_: i32,
pub message: String,
pub other_info: Option<CCErrorOtherInfo>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CoinDeskResponse<T> {
#[serde(rename = "Data")]
pub data: Option<T>,
#[serde(rename = "Err")]
pub error: Option<CCError>,
}
#[cfg(test)]
mod tests {
#[test]
fn unit_test_nullable_field() -> () {
use serde_json;
use crate::schemas;
let d: String = String::from("{\"Data\":{}, \"Err\":{\"type\": 23, \"message\": \"hello\", \"other_info\":null}}");
let response: schemas::CoinDeskResponse<String> = serde_json::from_str(&d.to_string().replace("{}", "null")).unwrap();
assert_eq!(response.data, None);
}
}