Skip to main content

overpass_lib/overpass/
server.rs

1use std::{borrow::Cow, sync::LazyLock};
2use crate::{Overpass, OverpassError, OverpassQL, OverpassResult, Query};
3use reqwest::Client;
4
5static CLIENT: LazyLock<Client> = LazyLock::new(|| Client::new());
6
7/// Makes an HTTP request to an Overpass API server to evaluate queries.
8///
9/// This implements [Default] with the official API server URL and a shared static HTTP client.
10/// This means you will usually not need to construct your own instance, you can use
11/// `OverpassServer::default()` directly.
12#[derive(Debug)]
13pub struct OverpassServer {
14    pub client: Cow<'static, Client>,
15    pub url: String,
16}
17
18impl Default for OverpassServer {
19    fn default() -> Self {
20        Self {
21            client: Cow::Borrowed(&CLIENT),
22            url: String::from("https://overpass-api.de/api/interpreter"),
23        }
24    }
25}
26
27impl Overpass for OverpassServer {
28    async fn evaluate(&self, query: &Query<'_>) -> Result<OverpassResult, OverpassError> {
29        let mut body = String::new();
30        query.fmt_oql(&mut body).map_err(|e| OverpassError::Query(e))?;
31
32        let req = self.client.post(&self.url).body(body).build()
33            .map_err(|e| OverpassError::Request(e))?;
34        let res = self.client.execute(req).await
35            .map_err(|e| OverpassError::Request(e))?;
36
37        match res.bytes().await {
38            Err(e) => Err(OverpassError::Request(e)),
39            Ok(b) => serde_json::from_slice(&b).map_err(|e| OverpassError::Parse(e)),
40        }
41    }
42}
43
44#[cfg(test)]
45mod test {
46    use std::collections::HashSet;
47    use crate::{ElementId, FilterSet, FilterType, Set};
48
49    use super::*;
50
51    #[tokio::test]
52    #[ignore]
53    async fn server() {
54        let q = OverpassServer::default().evaluate(
55            &Query::from(Set::Filter(FilterSet {
56                filter_type: FilterType::Node,
57                id_filters: HashSet::from([3359850618]),
58                ..Default::default()
59            })),
60        ).await;
61
62        let ids = q.unwrap().elements.into_iter().map(|e| e.id()).collect::<HashSet<ElementId>>();
63        assert_eq!(ids, HashSet::from([ElementId::Node(3359850618)]));
64    }
65}