#[cfg(feature = "chrono")]
use crate::traits::FromTushareValueWithFormat;
#[cfg(feature = "chrono")]
use crate::error::TushareError;
#[cfg(feature = "chrono")]
impl FromTushareValueWithFormat for chrono::NaiveDate {
fn from_tushare_value_with_format(
value: &serde_json::Value,
format: &str,
) -> Result<Self, TushareError> {
match value {
serde_json::Value::String(s) => {
chrono::NaiveDate::parse_from_str(s, format)
.map_err(|e| TushareError::ParseError(
format!("Failed to parse date '{}' with format '{}': {}", s, format, e)
))
}
serde_json::Value::Number(n) => {
if let Some(i) = n.as_i64() {
let date_str = i.to_string();
if date_str.len() == 8 {
if let Ok(date) = chrono::NaiveDate::parse_from_str(&date_str, "%Y%m%d") {
return Ok(date);
}
}
chrono::NaiveDate::parse_from_str(&date_str, format)
.map_err(|e| TushareError::ParseError(
format!("Failed to parse numeric date '{}' with format '{}': {}", date_str, format, e)
))
} else {
Err(TushareError::ParseError(
format!("Invalid numeric date value: {}", n)
))
}
}
_ => Err(TushareError::ParseError(
format!("Expected string or number for date parsing, got: {:?}", value)
)),
}
}
}
#[cfg(feature = "chrono")]
impl FromTushareValueWithFormat for chrono::NaiveDateTime {
fn from_tushare_value_with_format(
value: &serde_json::Value,
format: &str,
) -> Result<Self, TushareError> {
match value {
serde_json::Value::String(s) => {
chrono::NaiveDateTime::parse_from_str(s, format)
.map_err(|e| TushareError::ParseError(
format!("Failed to parse datetime '{}' with format '{}': {}", s, format, e)
))
}
serde_json::Value::Number(n) => {
let datetime_str = n.to_string();
chrono::NaiveDateTime::parse_from_str(&datetime_str, format)
.map_err(|e| TushareError::ParseError(
format!("Failed to parse numeric datetime '{}' with format '{}': {}", datetime_str, format, e)
))
}
_ => Err(TushareError::ParseError(
format!("Expected string or number for datetime parsing, got: {:?}", value)
)),
}
}
}
#[cfg(feature = "chrono")]
impl FromTushareValueWithFormat for chrono::DateTime<chrono::Utc> {
fn from_tushare_value_with_format(
value: &serde_json::Value,
format: &str,
) -> Result<Self, TushareError> {
match value {
serde_json::Value::String(s) => {
chrono::DateTime::parse_from_str(s, format)
.map(|dt| dt.with_timezone(&chrono::Utc))
.map_err(|e| TushareError::ParseError(
format!("Failed to parse UTC datetime '{}' with format '{}': {}", s, format, e)
))
}
serde_json::Value::Number(n) => {
let datetime_str = n.to_string();
chrono::DateTime::parse_from_str(&datetime_str, format)
.map(|dt| dt.with_timezone(&chrono::Utc))
.map_err(|e| TushareError::ParseError(
format!("Failed to parse numeric UTC datetime '{}' with format '{}': {}", datetime_str, format, e)
))
}
_ => Err(TushareError::ParseError(
format!("Expected string or number for UTC datetime parsing, got: {:?}", value)
)),
}
}
}