openmeteo-rs 1.0.0

Rust client for the Open-Meteo weather API.
Documentation
use std::borrow::Cow;

use crate::query::AsApiStr;

/// Hourly variables for the air-quality endpoint.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum AirQualityHourlyVar {
    /// Particulate matter PM10.
    Pm10,
    /// Particulate matter PM2.5.
    Pm2_5,
    /// Carbon monoxide.
    CarbonMonoxide,
    /// Carbon dioxide.
    CarbonDioxide,
    /// Nitrogen dioxide.
    NitrogenDioxide,
    /// Sulphur dioxide.
    SulphurDioxide,
    /// Ozone.
    Ozone,
    /// Aerosol optical depth.
    AerosolOpticalDepth,
    /// Dust.
    Dust,
    /// UV index.
    UvIndex,
    /// Clear-sky UV index.
    UvIndexClearSky,
    /// Ammonia.
    Ammonia,
    /// Methane.
    Methane,
    /// Alder pollen.
    AlderPollen,
    /// Birch pollen.
    BirchPollen,
    /// Grass pollen.
    GrassPollen,
    /// Mugwort pollen.
    MugwortPollen,
    /// Olive pollen.
    OlivePollen,
    /// Ragweed pollen.
    RagweedPollen,
    /// European air quality index.
    EuropeanAqi,
    /// European AQI for PM2.5.
    EuropeanAqiPm2_5,
    /// European AQI for PM10.
    EuropeanAqiPm10,
    /// European AQI for nitrogen dioxide.
    EuropeanAqiNitrogenDioxide,
    /// European AQI for ozone.
    EuropeanAqiOzone,
    /// European AQI for sulphur dioxide.
    EuropeanAqiSulphurDioxide,
    /// United States air quality index.
    UsAqi,
    /// United States AQI for PM2.5.
    UsAqiPm2_5,
    /// United States AQI for PM10.
    UsAqiPm10,
    /// United States AQI for nitrogen dioxide.
    UsAqiNitrogenDioxide,
    /// United States AQI for ozone.
    UsAqiOzone,
    /// United States AQI for sulphur dioxide.
    UsAqiSulphurDioxide,
    /// United States AQI for carbon monoxide.
    UsAqiCarbonMonoxide,
    /// Formaldehyde.
    Formaldehyde,
    /// Glyoxal.
    Glyoxal,
    /// Non-methane volatile organic compounds.
    NonMethaneVolatileOrganicCompounds,
    /// PM10 caused by wildfires.
    Pm10Wildfires,
    /// Peroxyacyl nitrates.
    PeroxyacylNitrates,
    /// Secondary inorganic aerosol.
    SecondaryInorganicAerosol,
    /// Residential elementary carbon.
    ResidentialElementaryCarbon,
    /// Total elementary carbon.
    TotalElementaryCarbon,
    /// PM2.5 total organic matter.
    Pm2_5TotalOrganicMatter,
    /// Sea-salt aerosol.
    SeaSaltAerosol,
    /// Nitrogen monoxide.
    NitrogenMonoxide,
    /// Exact Open-Meteo air-quality variable token not yet represented by this enum.
    Other(Cow<'static, str>),
}

impl AirQualityHourlyVar {
    /// Creates an exact Open-Meteo air-quality variable token not yet represented by this enum.
    ///
    /// The token is passed through unchanged and is not validated by the crate.
    pub fn other(token: impl Into<Cow<'static, str>>) -> Self {
        Self::Other(token.into())
    }
}

impl AsApiStr for AirQualityHourlyVar {
    fn as_api_str(&self) -> Cow<'static, str> {
        match self {
            Self::Pm10 => Cow::Borrowed("pm10"),
            Self::Pm2_5 => Cow::Borrowed("pm2_5"),
            Self::CarbonMonoxide => Cow::Borrowed("carbon_monoxide"),
            Self::CarbonDioxide => Cow::Borrowed("carbon_dioxide"),
            Self::NitrogenDioxide => Cow::Borrowed("nitrogen_dioxide"),
            Self::SulphurDioxide => Cow::Borrowed("sulphur_dioxide"),
            Self::Ozone => Cow::Borrowed("ozone"),
            Self::AerosolOpticalDepth => Cow::Borrowed("aerosol_optical_depth"),
            Self::Dust => Cow::Borrowed("dust"),
            Self::UvIndex => Cow::Borrowed("uv_index"),
            Self::UvIndexClearSky => Cow::Borrowed("uv_index_clear_sky"),
            Self::Ammonia => Cow::Borrowed("ammonia"),
            Self::Methane => Cow::Borrowed("methane"),
            Self::AlderPollen => Cow::Borrowed("alder_pollen"),
            Self::BirchPollen => Cow::Borrowed("birch_pollen"),
            Self::GrassPollen => Cow::Borrowed("grass_pollen"),
            Self::MugwortPollen => Cow::Borrowed("mugwort_pollen"),
            Self::OlivePollen => Cow::Borrowed("olive_pollen"),
            Self::RagweedPollen => Cow::Borrowed("ragweed_pollen"),
            Self::EuropeanAqi => Cow::Borrowed("european_aqi"),
            Self::EuropeanAqiPm2_5 => Cow::Borrowed("european_aqi_pm2_5"),
            Self::EuropeanAqiPm10 => Cow::Borrowed("european_aqi_pm10"),
            Self::EuropeanAqiNitrogenDioxide => Cow::Borrowed("european_aqi_nitrogen_dioxide"),
            Self::EuropeanAqiOzone => Cow::Borrowed("european_aqi_ozone"),
            Self::EuropeanAqiSulphurDioxide => Cow::Borrowed("european_aqi_sulphur_dioxide"),
            Self::UsAqi => Cow::Borrowed("us_aqi"),
            Self::UsAqiPm2_5 => Cow::Borrowed("us_aqi_pm2_5"),
            Self::UsAqiPm10 => Cow::Borrowed("us_aqi_pm10"),
            Self::UsAqiNitrogenDioxide => Cow::Borrowed("us_aqi_nitrogen_dioxide"),
            Self::UsAqiOzone => Cow::Borrowed("us_aqi_ozone"),
            Self::UsAqiSulphurDioxide => Cow::Borrowed("us_aqi_sulphur_dioxide"),
            Self::UsAqiCarbonMonoxide => Cow::Borrowed("us_aqi_carbon_monoxide"),
            Self::Formaldehyde => Cow::Borrowed("formaldehyde"),
            Self::Glyoxal => Cow::Borrowed("glyoxal"),
            Self::NonMethaneVolatileOrganicCompounds => {
                Cow::Borrowed("non_methane_volatile_organic_compounds")
            }
            Self::Pm10Wildfires => Cow::Borrowed("pm10_wildfires"),
            Self::PeroxyacylNitrates => Cow::Borrowed("peroxyacyl_nitrates"),
            Self::SecondaryInorganicAerosol => Cow::Borrowed("secondary_inorganic_aerosol"),
            Self::ResidentialElementaryCarbon => Cow::Borrowed("residential_elementary_carbon"),
            Self::TotalElementaryCarbon => Cow::Borrowed("total_elementary_carbon"),
            Self::Pm2_5TotalOrganicMatter => Cow::Borrowed("pm2_5_total_organic_matter"),
            Self::SeaSaltAerosol => Cow::Borrowed("sea_salt_aerosol"),
            Self::NitrogenMonoxide => Cow::Borrowed("nitrogen_monoxide"),
            Self::Other(token) => token.clone(),
        }
    }
}

/// Current-condition variables for the air-quality endpoint.
///
/// Open-Meteo documents `current=` as accepting every hourly air-quality
/// variable, so this alias intentionally exposes the full hourly set.
pub type AirQualityCurrentVar = AirQualityHourlyVar;

/// Air-quality domain selector.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum AirQualityDomain {
    /// Let Open-Meteo combine global and European domains automatically.
    Auto,
    /// CAMS European domain.
    CamsEurope,
    /// CAMS global domain.
    CamsGlobal,
}

impl AsApiStr for AirQualityDomain {
    fn as_api_str(&self) -> Cow<'static, str> {
        Cow::Borrowed(match self {
            Self::Auto => "auto",
            Self::CamsEurope => "cams_europe",
            Self::CamsGlobal => "cams_global",
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn custom_air_quality_variable_token_is_passed_through() {
        assert_eq!(
            AirQualityHourlyVar::other("new_air_quality_metric").as_api_str(),
            "new_air_quality_metric"
        );
    }
}