【time-rs】月份枚举实现

rust 复制代码
// 基本定义
#[repr(u8)]
pub enum Month {
    January = 1,
    February = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12,
}

1. 枚举定义和特征

月份枚举1 开始编号而不是 0,这符合日常习惯:

rust 复制代码
#[repr(u8)]  // 确保以 u8 形式存储
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Month {
    January = 1,    // 不是 0!
    // ... 其他月份
    December = 12,
}

2. 核心方法实现

2.1 创建和转换方法

rust 复制代码
impl Month {
    /// 从数字创建月份
    pub(crate) const fn from_number(n: NonZero<u8>) -> Result<Self, error::ComponentRange> {
        match n.get() {
            1 => Ok(January),
            // ... 2-11
            12 => Ok(December),
            n => Err(error::ComponentRange { /* 错误详情 */ }),
        }
    }
    
    /// 获取月份天数(考虑闰年)
    pub const fn length(self, year: i32) -> u8 {
        util::days_in_month(self, year)
    }
}

2.2 月份导航方法

rust 复制代码
impl Month {
    /// 获取上个月
    pub const fn previous(self) -> Self {
        match self {
            January => December,
            February => January,
            // ... 其他匹配
        }
    }
    
    /// 获取下个月
    pub const fn next(self) -> Self {
        match self {
            January => February,
            // ... 其他匹配
            December => January,
        }
    }
    
    /// 获取第 n 个下个月
    pub const fn nth_next(self, n: u8) -> Self {
        match (self as u8 - 1 + n % 12) % 12 {
            0 => January,
            // ... 1-10
            11 => December,
            _ => unreachable!(),
        }
    }
}

3. 特性实现

3.1 智能显示(SmartDisplay)

rust 复制代码
impl SmartDisplay for Month {
    type Metadata = MonthMetadata;
    
    fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
        match self {
            January => Metadata::new(7, self, MonthMetadata),   // "January" 长度 7
            February => Metadata::new(8, self, MonthMetadata),  // "February" 长度 8
            // ... 其他月份
        }
    }
    
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.pad(match self {
            January => "January",
            // ... 其他月份名称
        })
    }
}

3.2 标准特性实现

rust 复制代码
// 显示实现委托给 SmartDisplay
impl fmt::Display for Month {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        SmartDisplay::fmt(self, f)
    }
}

// 从字符串解析
impl FromStr for Month {
    type Err = error::InvalidVariant;
    
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "January" => Ok(January),
            // ... 其他月份名称
            _ => Err(error::InvalidVariant),
        }
    }
}

3.3 类型转换

rust 复制代码
// Month -> u8
impl From<Month> for u8 {
    fn from(month: Month) -> Self {
        month as Self  // 安全:月份值 1-12
    }
}

// u8 -> Month(安全转换)
impl TryFrom<u8> for Month {
    type Error = error::ComponentRange;
    
    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match NonZero::new(value) {
            Some(value) => Self::from_number(value),
            None => Err(/* 错误:值为 0 */),
        }
    }
}

4. 设计特点总结

特点 说明
类型安全 使用枚举而非整数,防止无效月份值
零成本抽象 使用 const 函数和内联优化
内存优化 使用 NonZero<u8>#[repr(u8)]
完整功能 支持显示、解析、导航、天数计算
实用 API 提供日常需要的月份操作

5. 使用示例

rust 复制代码
// 创建月份
let january = Month::January;
let february = Month::try_from(2).unwrap();

// 显示月份
println!("Current month: {}", january);  // "January"

// 计算天数(考虑闰年)
println!("Days in Feb 2020: {}", Month::February.length(2020));  // 29

// 月份导航
let next_month = january.next();          // February
let three_months_later = january.nth_next(3);  // April

// 类型转换
let month_num: u8 = january.into();       // 1
let from_str: Month = "March".parse().unwrap();  // Month::March
相关推荐
superman超哥14 小时前
Rust 错误处理模式:Result、?运算符与 anyhow 的最佳实践
开发语言·后端·rust·运算符·anyhow·rust 错误处理
Tony Bai1 天前
高并发后端:坚守 Go,还是拥抱 Rust?
开发语言·后端·golang·rust
哆啦code梦1 天前
Rust:高性能安全的现代编程语言
开发语言·rust
superman超哥1 天前
Rust 过程宏开发入门:编译期元编程的深度实践
开发语言·后端·rust·元编程·rust过程宏·编译期
借个火er1 天前
用 Tauri 2.0 + React + Rust 打造跨平台文件工具箱
react.js·rust
superman超哥1 天前
Rust Link-Time Optimization (LTO):跨边界的全局优化艺术
开发语言·后端·rust·lto·link-time·跨边界·优化艺术
superman超哥1 天前
Rust 编译优化选项配置:释放性能潜力的精细调控
开发语言·后端·rust·rust编译优化·精细调控·编译优化选项
superman超哥1 天前
Rust 日志级别与结构化日志:生产级可观测性实践
开发语言·后端·rust·可观测性·rust日志级别·rust结构化日志
superman超哥2 天前
Rust 减少内存分配策略:性能优化的内存管理艺术
开发语言·后端·性能优化·rust·内存管理·内存分配策略
superman超哥2 天前
Rust 并发性能调优:线程、异步与无锁的深度优化
开发语言·后端·rust·线程·异步·无锁·rust并发性能