use crate::client::{format_req_param, TrendsClient};
use crate::models::{InterestOverTime, TimelinePoint, WidgetToken};
use crate::{Result, TrendsError};
impl TrendsClient {
pub async fn interest_over_time(&self, token: &WidgetToken) -> Result<InterestOverTime> {
let url = "https://trends.google.com/trends/api/widgetdata/multiline";
let req_str = format_req_param(&token.request)?;
let tz_str = self.tz.to_string();
let params = vec![
("hl", self.hl.as_str()),
("tz", tz_str.as_str()),
("req", req_str.as_str()),
("token", token.token.as_str()),
];
let result = self.get_json_with_params(url, ¶ms).await?;
let default_obj = result.get("default").ok_or_else(|| {
TrendsError::TokenNotFound("Missing 'default' in multiline response".into())
})?;
let mut timeline = Vec::new();
if let Some(timeline_arr) = default_obj.get("timelineData").and_then(|t| t.as_array()) {
for item in timeline_arr {
let time = item
.get("time")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let formatted_time = item
.get("formattedTime")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let is_partial = item
.get("isPartial")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let mut values = Vec::new();
if let Some(val_arr) = item.get("value").and_then(|v| v.as_array()) {
for v in val_arr {
let raw = v.as_u64().ok_or_else(|| {
TrendsError::TokenNotFound(
"Non-numeric entry in timelineData.value".into(),
)
})?;
let parsed = u32::try_from(raw).map_err(|_| {
TrendsError::TokenNotFound(
"Out-of-range entry in timelineData.value".into(),
)
})?;
values.push(parsed);
}
}
timeline.push(TimelinePoint {
time,
formatted_time,
values,
is_partial,
});
}
}
let mut averages = Vec::new();
if let Some(avg_arr) = default_obj.get("averages").and_then(|a| a.as_array()) {
for v in avg_arr {
let raw = v.as_u64().ok_or_else(|| {
TrendsError::TokenNotFound("Non-numeric entry in averages".into())
})?;
let parsed = u32::try_from(raw).map_err(|_| {
TrendsError::TokenNotFound("Out-of-range entry in averages".into())
})?;
averages.push(parsed);
}
}
Ok(InterestOverTime {
timeline_data: timeline,
averages,
})
}
}