rust_flightweather 2.0.1

Decodes METAR and TAF
Documentation
////////////////////////////////////////////////////////////////////////////////////////////////////
// MIT License
//
// Copyright (c) 2023 Lily Hopkins
// Copyright (c) 2024 Rust-FlightWeather Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

//! This module contains the types that are used across the crate.

#[derive(PartialEq, Eq, Clone, Debug, Hash)]
/// Data that is provided in a metar which might be unknown.
/// Note that this differs from an `Option<T>` field which is used when data
/// might not be given at all. In the cases where `Data<T>` is used, data is
/// usually given but has been replaced in the METAR by slashes, indicating
/// that it is not known.
pub enum Data<T> {
    /// The data is known and given
    Known(T),
    /// The data isn't or can't be known
    Unknown,
}

impl<T> Data<T> {
    /// Unwraps the inner data type, panics otherwise
    pub fn unwrap(&self) -> &T {
        match self {
            Data::Known(v) => v,
            Data::Unknown => panic!("can not unwrap unknown data"),
        }
    }

    /// Mutably unwraps the inner data type, panics otherwise
    pub fn unwrap_mut(&mut self) -> &mut T {
        match self {
            Data::Known(v) => v,
            Data::Unknown => panic!("can not unwrap unknown data"),
        }
    }
}

#[derive(PartialEq, Eq, Clone, Debug)]
/// A struct to store time as it is represented in a METAR
pub struct Time {
    /// The date the METAR was made
    pub date: u8,
    /// The hour the METAR was made
    pub hour: u8,
    /// The minute the METAR was made
    pub minute: u8,
}

#[derive(PartialEq, Eq, Clone, Debug)]
/// Wind information.
pub struct Wind {
    /// The wind direction, in degrees
    pub dir: Data<WindDirection>,
    /// The current wind speed
    pub speed: Data<WindSpeed>,
    /// The gusting speed of the wind
    pub gusting: Option<WindSpeed>,
    /// The direction the wind may be varying between, smaller always comes first
    pub varying: Option<(Data<u16>, Data<u16>)>,
}

#[derive(PartialEq, Eq, Clone, Debug, Hash)]
/// The wind speed
pub enum WindSpeed {
    /// Winds calm
    Calm,
    /// Nautical miles per hour
    Knot(u16),
    /// Metres per second
    MetresPerSecond(u16),
    /// Kilometres per hour
    KilometresPerHour(u16),
}

impl WindSpeed {
    pub(crate) fn clone_changing_contents(&self, new_contents: u16) -> Self {
        match self {
            WindSpeed::Calm => WindSpeed::Calm,
            WindSpeed::Knot(_) => WindSpeed::Knot(new_contents),
            WindSpeed::MetresPerSecond(_) => WindSpeed::MetresPerSecond(new_contents),
            WindSpeed::KilometresPerHour(_) => WindSpeed::KilometresPerHour(new_contents),
        }
    }
}

#[derive(PartialEq, Eq, Clone, Debug, Hash)]
/// A representation of the wind direction
pub enum WindDirection {
    /// A heading defining wind direction
    Heading(u16),
    /// Wind direction is variable
    Variable,
    /// Wind speed is above 49mps or 99kt
    Above,
}

#[derive(PartialEq, Clone, Debug)]
/// Horizontal visibility
pub enum Visibility {
    /// Visibility OK
    Cavok,
    /// Metres
    Metres(u16),
    /// Statute miles, usually used in the US
    StatuteMiles(f32),
}

#[derive(PartialEq, Eq, Clone, Debug)]
/// Vertical visibility measurement
pub enum VertVisibility {
    /// A distance of vertical visibility
    Distance(u16),
    /// The vertical visibility value is present, so is reduced, but by an amount that hasn't or
    /// can't be measured
    ReducedByUnknownAmount,
}

#[derive(PartialEq, Eq, Clone, Debug, Hash)]
/// Cloud state
pub enum Clouds {
    /// No cloud was detected, also set for CAVOK
    NoCloudDetected,
    /// No significant cloud was detected below 5000ft
    NoSignificantCloud,
    /// Layers of cloud, described elsewhere
    CloudLayers,
}

#[derive(PartialEq, Eq, Clone, Debug)]
/// Cloud cover
pub enum CloudLayer {
    /// Few clouds (1/8)
    Few(CloudType, Option<u16>),
    /// Scattered cloud cover (3/8)
    Scattered(CloudType, Option<u16>),
    /// Broken cloud cover (5/8)
    Broken(CloudType, Option<u16>),
    /// Overcast cloud cover (7/8)
    Overcast(CloudType, Option<u16>),
    /// Cloud cover of an unknown density
    Unknown(CloudType, Option<u16>),
}

#[derive(PartialEq, Eq, Clone, Debug)]
/// A cloud type description
pub enum CloudType {
    /// A normal cloud
    Normal,
    /// A cumulonimbus cloud
    Cumulonimbus,
    /// A towering cumulus cloud
    ToweringCumulus,
    /// An unknown cloud type
    Unknown,
}

#[derive(PartialEq, Eq, Clone, Debug)]
/// A weather information block
pub struct Weather {
    /// The intensity of this weather block
    pub intensity: WeatherIntensity,
    /// The weather condition/s this block describes.
    pub conditions: Vec<WeatherCondition>,
}

#[derive(PartialEq, Eq, Clone, Debug)]
/// Intensity of weather
pub enum WeatherIntensity {
    /// Light (-)
    Light,
    /// Moderate (no prefix)
    Moderate,
    /// Heavy (+)
    Heavy,
    /// In the vicinity (VC)
    InVicinity,
    /// Recent (RE)
    Recent,
}

#[derive(PartialEq, Eq, Clone, Debug)]
/// Descriptor of weather
pub enum WeatherCondition {
    /// Descriptor – Shallow (MI)
    Shallow,
    /// Descriptor – Partial (PR)
    Partial,
    /// Descriptor – Patches (BC)
    Patches,
    /// Descriptor – Low drifting (DR)
    LowDrifting,
    /// Descriptor – Blowing (BL)
    Blowing,
    /// Descriptor – Showers (SH)
    Showers,
    /// Descriptor – Thunderstorm (TS)
    Thunderstorm,
    /// Descriptor – Freezing (FZ)
    Freezing,
    /// Precipitation – Rain (RA)
    Rain,
    /// Precipitation – Drizzle (DZ)
    Drizzle,
    /// Precipitation – Snow (SN)
    Snow,
    /// Precipitation – Snow Grains (SG)
    SnowGrains,
    /// Precipitation – Ice Crystals (IC)
    IceCrystals,
    /// Precipitation – Ice pellets (PL)
    IcePellets,
    /// Precipitation – Hail (including small hail in the US) (GR)
    Hail,
    /// Precipitation – Snow Pellets and/or Small Hail (except in US) (GS)
    SnowPelletsOrSmallHail,
    /// Precipitation – Unknown precipitation (UP)
    UnknownPrecipitation,
    /// Obscuration – Fog (FG)
    Fog,
    /// Obscuration – Volcanic Ash (VA)
    VolcanicAsh,
    /// Obscuration – Mist (BR)
    Mist,
    /// Obscuration – Haze (HZ)
    Haze,
    /// Obscuration – Widespread dust (DU)
    WidespreadDust,
    /// Obscuration – Smoke (FU)
    Smoke,
    /// Obscuration – Sand (SA)
    Sand,
    /// Obscuration – Spray (PY)
    Spray,
    /// Other – Squall (SQ)
    Squall,
    /// Other – Dust or Sand Whirls (PO)
    Dust,
    /// Other – Duststorm (DS)
    Duststorm,
    /// Other – Sandstorm (SS)
    Sandstorm,
    /// Other – Funnel Cloud (FC)
    FunnelCloud,
}