///|
fn visibility_to_meters(visibility : Visibility) -> Int? {
match visibility.unit {
Meters => Some(visibility.value)
StatuteMiles => Some(visibility.value * 1609)
}
}
///|
fn ceiling_feet(report : MetarReport) -> Int? {
let mut best : Int? = None
for cloud in report.clouds {
match (cloud.coverage, cloud.height_feet) {
(Broken | Overcast, Some(height)) =>
match best {
Some(current) => if height < current { best = Some(height) }
None => best = Some(height)
}
_ => ()
}
}
best
}
///|
pub fn flight_category_to_string(category : FlightCategory) -> String {
match category {
VFR => "VFR"
MVFR => "MVFR"
IFR => "IFR"
LIFR => "LIFR"
UnknownCategory => "UNKNOWN"
}
}
///|
/// Classify a report using configurable visibility and ceiling thresholds.
pub fn classify(
report : MetarReport,
rules? : FlightCategoryRules = standard_rules(),
) -> FlightCategory {
let visibility = match report.visibility {
Some(value) => visibility_to_meters(value)
None => None
}
let ceiling = ceiling_feet(report)
match (visibility, ceiling) {
(None, None) => UnknownCategory
_ => {
let low_visibility = match visibility {
Some(value) => value
None => 999999
}
let low_ceiling = match ceiling {
Some(value) => value
None => 999999
}
if low_visibility < rules.lifr_visibility_meters ||
low_ceiling < rules.lifr_ceiling_feet {
LIFR
} else if low_visibility < rules.ifr_visibility_meters ||
low_ceiling < rules.ifr_ceiling_feet {
IFR
} else if low_visibility < rules.mvfr_visibility_meters ||
low_ceiling < rules.mvfr_ceiling_feet {
MVFR
} else {
VFR
}
}
}
}