home.wezm.net/src/climate.rs

64 lines
1.6 KiB
Rust

use core::fmt;
use jiff::Zoned;
use serde::Serialize;
// https://reg.bom.gov.au/climate/averages/tables/cw_040861.shtml
static MAXIMUMS: [f32; 12] = [
29.1, 28.9, 28.0, 26.1, 23.6, 21.5, 21.1, 22.3, 24.3, 25.7, 27.3, 28.4,
];
static MINIMUMS: [f32; 12] = [
21.3, 21.4, 20.3, 17.1, 13.7, 11.3, 9.7, 10.0, 13.0, 15.7, 18.0, 20.0,
];
pub enum Season {
Summer,
Autumn,
Winter,
Spring,
}
#[derive(Serialize)]
pub struct Climate {
month: String,
min: f32,
max: f32,
}
pub fn season(now: &Zoned) -> Season {
// NOTE: Cast is safe jiff guarantees month is 1 to 12
match now.month() {
1..=2 | 12 => Season::Summer,
3..=5 => Season::Autumn,
6..=8 => Season::Winter,
9..=11 => Season::Spring,
_ => unreachable!("jiff guarantees month is 1 to 12"),
}
}
pub fn climate(now: &Zoned) -> Climate {
let month = (now.month() - 1) as usize;
let min = MINIMUMS[month];
let max = MAXIMUMS[month];
let month_name = now.strftime("%B").to_string();
Climate {
min,
max,
month: month_name,
}
}
impl fmt::Display for Season {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let (_emoji, name) = match self {
Season::Summer => ("🏖️", "summer"),
Season::Autumn => ("🍂", "autumn"),
Season::Winter => ("🧣", "winter"),
Season::Spring => ("🌱", "spring"),
};
// f.write_str("<span aria-hidden=\"true\">")?;
// f.write_str(emoji)?;
// f.write_str("</span> ")?;
f.write_str(name)
}
}