#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum IntervalResolution {
QuarterHour,
HalfHour,
Hour,
Day,
Month,
Year,
Custom(u32),
}
impl IntervalResolution {
#[must_use]
pub fn as_seconds(self) -> u32 {
match self {
Self::QuarterHour => 900,
Self::HalfHour => 1800,
Self::Hour => 3600,
Self::Day => 86400,
Self::Month => 30 * 86400,
Self::Year => 365 * 86400,
Self::Custom(s) => s,
}
}
#[must_use]
pub fn label(self) -> &'static str {
match self {
Self::QuarterHour => "15-Minuten",
Self::HalfHour => "30-Minuten",
Self::Hour => "Stunde",
Self::Day => "Tag",
Self::Month => "Monat",
Self::Year => "Jahr",
Self::Custom(_) => "Benutzerdefiniert",
}
}
#[must_use]
pub fn from_seconds(s: u32) -> Option<Self> {
match s {
0 => None,
900 => Some(Self::QuarterHour),
1800 => Some(Self::HalfHour),
3600 => Some(Self::Hour),
86400 => Some(Self::Day),
_ => Some(Self::Custom(s)),
}
}
#[must_use]
pub fn is_subhourly(self) -> bool {
matches!(self, Self::QuarterHour | Self::HalfHour)
}
}
impl std::fmt::Display for IntervalResolution {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}s ({})", self.as_seconds(), self.label())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn quarter_hour_is_900s() {
assert_eq!(IntervalResolution::QuarterHour.as_seconds(), 900);
}
#[test]
fn from_seconds_round_trip() {
for r in [
IntervalResolution::QuarterHour,
IntervalResolution::HalfHour,
IntervalResolution::Hour,
IntervalResolution::Day,
] {
let s = r.as_seconds();
assert_eq!(IntervalResolution::from_seconds(s), Some(r));
}
}
#[test]
fn zero_returns_none() {
assert!(IntervalResolution::from_seconds(0).is_none());
}
#[test]
fn custom_seconds_preserved() {
let r = IntervalResolution::Custom(7200);
assert_eq!(r.as_seconds(), 7200);
assert!(!r.is_subhourly());
}
#[test]
fn subhourly_detection() {
assert!(IntervalResolution::QuarterHour.is_subhourly());
assert!(IntervalResolution::HalfHour.is_subhourly());
assert!(!IntervalResolution::Hour.is_subhourly());
assert!(!IntervalResolution::Day.is_subhourly());
}
}