use crate::{ArcGISClient, Result};
use tracing::instrument;
use super::types::{
CategoriesResult, PlaceDetailsResult, PlaceSearchParameters, PlaceSearchResult,
};
#[derive(Clone)]
pub struct PlacesClient<'a> {
url: String,
client: &'a ArcGISClient,
}
impl<'a> PlacesClient<'a> {
pub fn new(client: &'a ArcGISClient) -> Self {
PlacesClient {
url: "https://places-api.arcgis.com/arcgis/rest/services/places-service/v1".to_string(),
client,
}
}
pub fn with_url(url: impl Into<String>, client: &'a ArcGISClient) -> Self {
PlacesClient {
url: url.into(),
client,
}
}
#[instrument(skip(self, params))]
pub async fn find_places_near_point(
&self,
params: PlaceSearchParameters,
) -> Result<PlaceSearchResult> {
tracing::debug!(
x = params.x(),
y = params.y(),
radius = ?params.radius(),
"Searching for places"
);
let search_url = format!("{}/places/near-point", self.url);
let mut request = self
.client
.http()
.get(&search_url)
.query(&[
("x", params.x().to_string()),
("y", params.y().to_string()),
("f", "json".to_string()),
])
.query(¶ms);
if let Some(token) = self.client.get_token_if_required().await? {
request = request.query(&[("token", token)]);
}
let response = request.send().await?;
let result: PlaceSearchResult = response.json().await?;
tracing::debug!(count = result.results().len(), "Places found");
Ok(result)
}
#[instrument(skip(self))]
pub async fn get_place_details(&self, place_id: &str) -> Result<PlaceDetailsResult> {
tracing::debug!(place_id = %place_id, "Getting place details");
let details_url = format!("{}/places/{}", self.url, place_id);
let mut request = self.client.http().get(&details_url).query(&[("f", "json")]);
if let Some(token) = self.client.get_token_if_required().await? {
request = request.query(&[("token", token)]);
}
let response = request.send().await?;
let result: PlaceDetailsResult = response.json().await?;
tracing::debug!(place_id = %place_id, "Place details retrieved");
Ok(result)
}
#[instrument(skip(self))]
pub async fn get_categories(&self) -> Result<CategoriesResult> {
tracing::debug!("Getting place categories");
let categories_url = format!("{}/categories", self.url);
let mut request = self
.client
.http()
.get(&categories_url)
.query(&[("f", "json")]);
if let Some(token) = self.client.get_token_if_required().await? {
request = request.query(&[("token", token)]);
}
let response = request.send().await?;
let result: CategoriesResult = response.json().await?;
tracing::debug!(count = result.categories().len(), "Categories retrieved");
Ok(result)
}
}