openmeteo-rs 1.0.0

Rust client for the Open-Meteo weather API.
Documentation
use openmeteo_rs::{Client, Result};
use wiremock::matchers::{method, path, query_param};
use wiremock::{Mock, MockServer, ResponseTemplate};

const GEOCODING_FIXTURE: &str = include_str!("fixtures/geocoding_zurich.json");
const EMPTY_GEOCODING_FIXTURE: &str = include_str!("fixtures/geocoding_empty_results.json");

#[tokio::test]
async fn geocoding_request_is_sent_and_decoded_against_fixture() -> Result<()> {
    let server = MockServer::start().await;
    Mock::given(method("GET"))
        .and(path("/v1/search"))
        .and(query_param("name", "Zurich"))
        .and(query_param("count", "2"))
        .and(query_param("language", "en"))
        .and(query_param("country_code", "CH"))
        .respond_with(
            ResponseTemplate::new(200).set_body_raw(GEOCODING_FIXTURE, "application/json"),
        )
        .mount(&server)
        .await;

    let client = Client::builder()
        .geocoding_base_url(server.uri())?
        .build()?;

    let locations = client
        .geocode("Zurich")
        .count(2)
        .language("en")
        .country_code("CH")
        .send()
        .await?;

    assert_eq!(locations.len(), 2);
    assert_eq!(locations[0].id, 2657896);
    assert_eq!(locations[0].name, "Zurich");
    assert_eq!(locations[0].country_code.as_deref(), Some("CH"));
    assert_eq!(locations[0].timezone.as_deref(), Some("Europe/Zurich"));
    assert_eq!(locations[0].postcodes.as_ref().unwrap()[0], "8000");
    assert_eq!(locations[1].country.as_deref(), Some("The Netherlands"));

    Ok(())
}

#[tokio::test]
async fn geocoding_empty_results_decode_to_empty_vec() -> Result<()> {
    let server = MockServer::start().await;
    Mock::given(method("GET"))
        .and(path("/v1/search"))
        .and(query_param("name", "not-a-real-place"))
        .respond_with(
            ResponseTemplate::new(200).set_body_raw(EMPTY_GEOCODING_FIXTURE, "application/json"),
        )
        .mount(&server)
        .await;

    let client = Client::builder()
        .geocoding_base_url(server.uri())?
        .build()?;

    let locations = client.geocode("not-a-real-place").send().await?;

    assert!(locations.is_empty());

    Ok(())
}