#[cfg(feature = "chrono")]
use crate::error::TushareError;
#[cfg(feature = "chrono")]
use crate::traits::FromTushareValueWithFormat;
#[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
))),
}
}
}