use crate::client::{format_req_param, TrendsClient};
use crate::models::{Coordinates, GeoPoint, GeoResolution, InterestByRegion, WidgetToken};
use crate::{Result, TrendsError};
impl TrendsClient {
pub async fn interest_by_region(
&self,
token: &WidgetToken,
resolution: GeoResolution,
) -> Result<InterestByRegion> {
let url = "https://trends.google.com/trends/api/widgetdata/comparedgeo";
let mut request_obj = token.request.clone();
if let Some(obj) = request_obj.as_object_mut() {
obj.insert(
"resolution".to_string(),
serde_json::json!(resolution.as_str()),
);
}
let req_str = format_req_param(&request_obj)?;
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 comparedgeo response".into())
})?;
let mut geo_map = Vec::new();
if let Some(geo_arr) = default_obj.get("geoMapData").and_then(|t| t.as_array()) {
for item in geo_arr {
let geo_code = item
.get("geoCode")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let geo_name = item
.get("geoName")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
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 geoMapData.value".into(),
)
})?;
let parsed = u32::try_from(raw).map_err(|_| {
TrendsError::TokenNotFound(
"Out-of-range entry in geoMapData.value".into(),
)
})?;
values.push(parsed);
}
}
let coordinates = if let Some(coords) = item.get("coordinates") {
let lat = coords.get("lat").and_then(|v| v.as_f64()).unwrap_or(0.0);
let lng = coords.get("lng").and_then(|v| v.as_f64()).unwrap_or(0.0);
Some(Coordinates { lat, lng })
} else {
None
};
geo_map.push(GeoPoint {
geo_code,
geo_name,
values,
coordinates,
});
}
}
Ok(InterestByRegion {
geo_map_data: geo_map,
})
}
}