use crate::{errors::CandlesError, types::Candle};
use chrono::{DateTime, Duration};
use serde::Deserialize;
use serde_json::Value;
#[derive(Deserialize, Debug)]
pub struct DataWrapper<T> {
pub data: T,
}
#[derive(Deserialize, Debug)]
pub struct ResultWrapper<T> {
pub result: T,
}
#[derive(Deserialize, Debug)]
pub struct DataWrapperWithMsgCode<C, T> {
pub code: C,
pub msg: Option<String>,
pub data: T,
}
#[derive(Deserialize, Debug)]
pub struct DataWrapperWithStatusCode<C, T> {
pub code: C,
pub message: Option<String>,
pub data: T,
}
pub fn parse_string_to_f64(val: &Value, field: &str, index: usize) -> Result<f64, CandlesError> {
match val {
Value::String(s) => s.parse().map_err(|_| CandlesError::Other(format!("Failed to parse {field} at index {index}: {val}"))),
Value::Number(n) => n
.as_f64()
.ok_or_else(|| CandlesError::Other(format!("Failed to convert {field} to f64 at index {index}: {val}"))),
_ => Err(CandlesError::Other(format!("Invalid {field} type at index {index}: expected string or number, got {val}"))),
}
}
pub fn examine_candles(candles: &[Candle]) {
use chrono::Utc;
assert!(!candles.is_empty(), "Candles array is empty");
assert!(candles.len() >= 5, "Candles length is < 5");
for i in 1..candles.len() {
assert!(
candles[i].timestamp > candles[i - 1].timestamp,
"Candles are not in ascending order: candle at index {} ({}) should be after candle at index {} ({})",
i,
candles[i].timestamp,
i - 1,
candles[i - 1].timestamp
);
}
let candle = candles.last().unwrap();
assert!(
DateTime::from_timestamp_millis(candle.timestamp).is_some(),
"Timestamp {} is not valid milliseconds",
candle.timestamp
);
let candle_time = DateTime::from_timestamp_millis(candle.timestamp).unwrap();
let now = Utc::now();
assert!(
candle_time - Duration::seconds(3) <= now,
"Timestamp {}({}) is in the future, while now is {}",
candle_time,
candle.timestamp,
now
);
assert!(candle.high >= candle.low, "High ({}) should be >= low ({})", candle.high, candle.low);
assert!(candle.close > 0.0, "Close price {} should be positive", candle.close);
assert!(candle.volume >= 0.0, "Volume {} should be non-negative", candle.volume);
}