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 flood forecast requests.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum FloodModel {
    /// GloFAS v4 seamless flood model.
    GlofasV4Seamless,
    /// GloFAS v4 forecast model.
    GlofasV4Forecast,
    /// GloFAS v4 consolidated historical model.
    GlofasV4Consolidated,
    /// GloFAS v3 seamless flood model.
    GlofasV3Seamless,
    /// GloFAS v3 forecast model.
    GlofasV3Forecast,
    /// GloFAS v3 consolidated historical model.
    GlofasV3Consolidated,
    /// Exact Open-Meteo flood 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 FloodModel {
    /// Creates an exact Open-Meteo flood 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 FloodModel {
    fn as_api_str(&self) -> Cow<'static, str> {
        match self {
            Self::GlofasV4Seamless => Cow::Borrowed("seamless_v4"),
            Self::GlofasV4Forecast => Cow::Borrowed("forecast_v4"),
            Self::GlofasV4Consolidated => Cow::Borrowed("consolidated_v4"),
            Self::GlofasV3Seamless => Cow::Borrowed("seamless_v3"),
            Self::GlofasV3Forecast => Cow::Borrowed("forecast_v3"),
            Self::GlofasV3Consolidated => Cow::Borrowed("consolidated_v3"),
            Self::Other(token) => token.clone(),
        }
    }
}

/// Daily variables for flood forecast requests.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum FloodDailyVar {
    /// Daily river discharge.
    RiverDischarge,
    /// Ensemble mean river discharge.
    RiverDischargeMean,
    /// Ensemble median river discharge.
    RiverDischargeMedian,
    /// Ensemble maximum river discharge.
    RiverDischargeMax,
    /// Ensemble minimum river discharge.
    RiverDischargeMin,
    /// Ensemble 25th percentile river discharge.
    RiverDischargeP25,
    /// Ensemble 75th percentile river discharge.
    RiverDischargeP75,
    /// Exact Open-Meteo flood daily 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 FloodDailyVar {
    /// Creates an exact Open-Meteo flood daily 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 FloodDailyVar {
    fn as_api_str(&self) -> Cow<'static, str> {
        match self {
            Self::RiverDischarge => Cow::Borrowed("river_discharge"),
            Self::RiverDischargeMean => Cow::Borrowed("river_discharge_mean"),
            Self::RiverDischargeMedian => Cow::Borrowed("river_discharge_median"),
            Self::RiverDischargeMax => Cow::Borrowed("river_discharge_max"),
            Self::RiverDischargeMin => Cow::Borrowed("river_discharge_min"),
            Self::RiverDischargeP25 => Cow::Borrowed("river_discharge_p25"),
            Self::RiverDischargeP75 => Cow::Borrowed("river_discharge_p75"),
            Self::Other(token) => token.clone(),
        }
    }
}

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

    #[test]
    fn flood_model_tokens_are_formatted() {
        assert_eq!(FloodModel::GlofasV4Seamless.as_api_str(), "seamless_v4");
        assert_eq!(FloodModel::GlofasV4Forecast.as_api_str(), "forecast_v4");
        assert_eq!(
            FloodModel::GlofasV4Consolidated.as_api_str(),
            "consolidated_v4"
        );
        assert_eq!(FloodModel::GlofasV3Seamless.as_api_str(), "seamless_v3");
        assert_eq!(FloodModel::GlofasV3Forecast.as_api_str(), "forecast_v3");
        assert_eq!(
            FloodModel::GlofasV3Consolidated.as_api_str(),
            "consolidated_v3"
        );
        assert_eq!(
            FloodModel::other("custom_flood_model").as_api_str(),
            "custom_flood_model"
        );
    }

    #[test]
    fn flood_daily_tokens_are_formatted() {
        assert_eq!(
            FloodDailyVar::RiverDischarge.as_api_str(),
            "river_discharge"
        );
        assert_eq!(
            FloodDailyVar::RiverDischargeMean.as_api_str(),
            "river_discharge_mean"
        );
        assert_eq!(
            FloodDailyVar::RiverDischargeP75.as_api_str(),
            "river_discharge_p75"
        );
        assert_eq!(
            FloodDailyVar::other("custom_flood_var").as_api_str(),
            "custom_flood_var"
        );
    }
}