openmeteo-rs 1.0.0

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

use crate::query::AsApiStr;

/// Model selector for seasonal forecast requests.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SeasonalModel {
    /// Open-Meteo's seamless seasonal model selection.
    EcmwfSeasonalSeamless,
    /// ECMWF SEAS5 seasonal forecast.
    EcmwfSeas5,
    /// ECMWF EC46 sub-seasonal forecast.
    EcmwfEc46,
    /// Open-Meteo's seamless seasonal ensemble-mean model selection.
    EcmwfSeasonalEnsembleMeanSeamless,
    /// ECMWF SEAS5 ensemble-mean seasonal forecast.
    EcmwfSeas5EnsembleMean,
    /// ECMWF EC46 ensemble-mean sub-seasonal forecast.
    EcmwfEc46EnsembleMean,
    /// Exact Open-Meteo seasonal model token not yet represented by this enum.
    ///
    /// The token is passed through unchanged and is not validated by the crate.
    Other(Cow<'static, str>),
}

impl SeasonalModel {
    /// Creates an exact Open-Meteo seasonal model 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 SeasonalModel {
    fn as_api_str(&self) -> Cow<'static, str> {
        match self {
            Self::EcmwfSeasonalSeamless => Cow::Borrowed("ecmwf_seasonal_seamless"),
            Self::EcmwfSeas5 => Cow::Borrowed("ecmwf_seas5"),
            Self::EcmwfEc46 => Cow::Borrowed("ecmwf_ec46"),
            Self::EcmwfSeasonalEnsembleMeanSeamless => {
                Cow::Borrowed("ecmwf_seasonal_ensemble_mean_seamless")
            }
            Self::EcmwfSeas5EnsembleMean => Cow::Borrowed("ecmwf_seas5_ensemble_mean"),
            Self::EcmwfEc46EnsembleMean => Cow::Borrowed("ecmwf_ec46_ensemble_mean"),
            Self::Other(token) => token.clone(),
        }
    }
}

/// Monthly variables for seasonal forecast requests.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SeasonalMonthlyVar {
    /// Mean 2 m temperature.
    Temperature2mMean,
    /// Maximum 2 m temperature.
    Temperature2mMax,
    /// Minimum 2 m temperature.
    Temperature2mMin,
    /// Precipitation sum.
    PrecipitationSum,
    /// Exact Open-Meteo seasonal monthly variable token not yet represented by this enum.
    ///
    /// The token is passed through unchanged and is not validated by the crate.
    Other(Cow<'static, str>),
}

impl SeasonalMonthlyVar {
    /// Creates an exact Open-Meteo seasonal monthly 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 SeasonalMonthlyVar {
    fn as_api_str(&self) -> Cow<'static, str> {
        match self {
            Self::Temperature2mMean => Cow::Borrowed("temperature_2m_mean"),
            Self::Temperature2mMax => Cow::Borrowed("temperature_2m_max"),
            Self::Temperature2mMin => Cow::Borrowed("temperature_2m_min"),
            Self::PrecipitationSum => Cow::Borrowed("precipitation_sum"),
            Self::Other(token) => token.clone(),
        }
    }
}

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

    #[test]
    fn seasonal_tokens_are_formatted() {
        assert_eq!(
            SeasonalModel::EcmwfSeasonalSeamless.as_api_str(),
            "ecmwf_seasonal_seamless"
        );
        assert_eq!(SeasonalModel::EcmwfSeas5.as_api_str(), "ecmwf_seas5");
        assert_eq!(SeasonalModel::EcmwfEc46.as_api_str(), "ecmwf_ec46");
        assert_eq!(
            SeasonalModel::EcmwfSeasonalEnsembleMeanSeamless.as_api_str(),
            "ecmwf_seasonal_ensemble_mean_seamless"
        );
        assert_eq!(
            SeasonalModel::EcmwfSeas5EnsembleMean.as_api_str(),
            "ecmwf_seas5_ensemble_mean"
        );
        assert_eq!(
            SeasonalModel::EcmwfEc46EnsembleMean.as_api_str(),
            "ecmwf_ec46_ensemble_mean"
        );
        assert_eq!(
            SeasonalModel::other("custom_seasonal_model").as_api_str(),
            "custom_seasonal_model"
        );
        assert_eq!(
            SeasonalMonthlyVar::Temperature2mMean.as_api_str(),
            "temperature_2m_mean"
        );
        assert_eq!(
            SeasonalMonthlyVar::other("custom_monthly_var").as_api_str(),
            "custom_monthly_var"
        );
    }
}