【time-rs】解释://! Error that occurred at some stage of parsing(error/parse.rs)

这段Rust代码定义了一个解析错误的通用枚举类型 Parse,用于表示在时间解析过程中可能发生的各种错误。它是时间解析库中的核心错误类型。

枚举定义

rust 复制代码
#[non_exhaustive]
#[allow(variant_size_differences, reason = "only triggers on some platforms")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Parse {
    TryFromParsed(TryFromParsed),
    ParseFromDescription(ParseFromDescription),
    #[non_exhaustive]
    #[deprecated(
        since = "0.3.28",
        note = "no longer output. moved to the `ParseFromDescription` variant"
    )]
    UnexpectedTrailingCharacters {
        #[doc(hidden)]
        never: Infallible,
    },
}

属性说明:

  1. #[non_exhaustive]

    • 表示枚举未来可能添加新变体
    • 强制用户代码使用穷尽匹配,保持向后兼容
  2. #[allow(variant_size_differences)]

    • 允许变体大小不同(因为包含 Infallible 类型)
    • reason 属性说明:仅在某些平台上触发
  3. #[derive(...)]

    • 实现了 DebugCloneCopyPartialEqEq 等常见trait

变体详解

1. TryFromParsed(TryFromParsed)

  • 表示在从解析结果转换到目标类型时发生的错误
  • 例如:解析出的日期时间值超出目标类型的有效范围

2. ParseFromDescription(ParseFromDescription)

  • 表示根据格式描述进行解析时发生的错误
  • 例如:输入字符串与格式描述不匹配

3. UnexpectedTrailingCharacters(已弃用)

rust 复制代码
#[deprecated(since = "0.3.28", note = "...")]
UnexpectedTrailingCharacters {
    #[doc(hidden)]
    never: Infallible,
}
  • 已弃用:从 0.3.28 版本开始不再使用
  • 迁移 :功能已移至 ParseFromDescription 变体
  • Infallible:永不实例化的类型,确保该变体无法构造
  • 设计目的:保持API兼容性,同时逐步移除旧功能

Display trait 实现

rust 复制代码
impl fmt::Display for Parse {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::TryFromParsed(err) => err.fmt(f),
            Self::ParseFromDescription(err) => err.fmt(f),
            #[allow(deprecated)]
            Self::UnexpectedTrailingCharacters { never } => match *never {},
        }
    }
}

实现特点

  • 委托给内部错误的 Display 实现
  • 对于已弃用变体,使用 match *never {} 保证编译通过
  • #[allow(deprecated)] 允许使用已弃用的变体模式

Error trait 实现

rust 复制代码
impl core::error::Error for Parse {
    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
        match self {
            Self::TryFromParsed(err) => Some(err),
            Self::ParseFromDescription(err) => Some(err),
            #[allow(deprecated)]
            Self::UnexpectedTrailingCharacters { never } => match *never {},
        }
    }
}

特点

  • 实现 source() 方法,提供错误的根本原因
  • 支持错误链(error chain)
  • 同样处理了已弃用变体

与内部错误类型的转换

TryFromParsed 转换到 Parse

rust 复制代码
impl From<TryFromParsed> for Parse {
    fn from(err: TryFromParsed) -> Self {
        Self::TryFromParsed(err)
    }
}

Parse 尝试转换到 TryFromParsed

rust 复制代码
impl TryFrom<Parse> for TryFromParsed {
    type Error = error::DifferentVariant;

    fn try_from(err: Parse) -> Result<Self, Self::Error> {
        match err {
            Parse::TryFromParsed(err) => Ok(err),
            _ => Err(error::DifferentVariant),
        }
    }
}

ParseFromDescription 转换到 Parse

rust 复制代码
impl From<ParseFromDescription> for Parse {
    fn from(err: ParseFromDescription) -> Self {
        Self::ParseFromDescription(err)
    }
}

Parse 尝试转换到 ParseFromDescription

rust 复制代码
impl TryFrom<Parse> for ParseFromDescription {
    type Error = error::DifferentVariant;

    fn try_from(err: Parse) -> Result<Self, Self::Error> {
        match err {
            Parse::ParseFromDescription(err) => Ok(err),
            _ => Err(error::DifferentVariant),
        }
    }
}

转换模式总结

  • From<T>:总是成功,向上转换
  • TryFrom<Parse>:可能失败,向下转换
  • DifferentVariant:当错误类型不匹配时返回

与 crate::Error 的转换

向上转换:Parsecrate::Error

rust 复制代码
impl From<Parse> for crate::Error {
    fn from(err: Parse) -> Self {
        match err {
            Parse::TryFromParsed(err) => Self::TryFromParsed(err),
            Parse::ParseFromDescription(err) => Self::ParseFromDescription(err),
            #[allow(deprecated)]
            Parse::UnexpectedTrailingCharacters { never } => match never {},
        }
    }
}

处理已弃用变体

  • 对于 UnexpectedTrailingCharacters,使用 match never {} 保证不会执行
  • 确保编译通过,即使变体已弃用

向下转换:crate::ErrorParse

rust 复制代码
impl TryFrom<crate::Error> for Parse {
    type Error = error::DifferentVariant;

    fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
        match err {
            crate::Error::ParseFromDescription(err) => Ok(Self::ParseFromDescription(err)),
            #[allow(deprecated)]
            crate::Error::UnexpectedTrailingCharacters { never } => match never {},
            crate::Error::TryFromParsed(err) => Ok(Self::TryFromParsed(err)),
            _ => Err(error::DifferentVariant),
        }
    }
}

使用场景示例

解析时间字符串

rust 复制代码
use time::format_description;
use time::parsing::Parse;

fn parse_datetime(input: &str) -> Result<OffsetDateTime, Parse> {
    let format = format_description::parse("[year]-[month]-[day] [hour]:[minute]:[second]")?;
    let parsed = PrimitiveDateTime::parse(input, &format)?;
    Ok(parsed.into())
}

错误处理

rust 复制代码
match parse_datetime("2023-13-01 25:00:00") {
    Ok(dt) => println!("解析成功: {}", dt),
    Err(Parse::ParseFromDescription(err)) => {
        eprintln!("格式解析错误: {}", err);
    }
    Err(Parse::TryFromParsed(err)) => {
        eprintln!("类型转换错误: {}", err);
    }
}

设计特点

1. 分层错误处理

复制代码
crate::Error
├── Parse
│ ├── TryFromParsed
│ └── ParseFromDescription
└── Other errors...

2. 向后兼容性

  • 使用 #[deprecated]Infallible 平滑过渡
  • #[non_exhaustive] 保护未来扩展

3. 类型安全

  • 双向转换确保类型安全
  • 使用 TryFrom 进行安全的错误类型提取

4. 性能优化

  • #[inline] 提示内联优化
  • 大部分类型实现 Copy,减少分配

与其他错误类型的关系

错误类型 层级 用途
crate::Error 顶级 所有错误的容器
Parse 中间层 解析相关错误
TryFromParsed 具体层 转换错误
ParseFromDescription 具体层 格式解析错误

这种设计提供了灵活的错误处理机制,既支持通用的错误处理,也支持精确的错误类型匹配。

相关推荐
大卫小东(Sheldon)1 天前
Rust 推荐使用宏而非普通函数的场景
rust
doiito1 天前
【Agent Harness】为什么我把 JSON‑LD “编译成 DAG” 后,整个 Agent 平台立刻聪明了
ai·rust·架构设计·系统设计·ai agent
jump_jump1 天前
为了重玩金庸群侠传,我研究了一下 Ruffle 怎么复活 Flash
游戏·rust·github
星栈2 天前
Dioxus 多页面怎么做:`dioxus-router`、嵌套路由、`Outlet` 和页面组织,一篇给你讲顺
前端·rust·前端框架
Rust研习社4 天前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
红尘散仙5 天前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
vivo互联网技术5 天前
从 Web 到桌面:基于 Tauri 2.0 + Vue 3 打造 vivo 线下门店「大头贴」拍照体验系统
前端·rust
Rust研习社5 天前
这 8 个 Rust 学习资源值得每个新手收藏起来
后端·rust·编程语言
星栈6 天前
10 分钟跑起第一个 Dioxus 应用:`dx` CLI、`rsx!` 和热更新好不好用
前端·rust·前端框架
望眼欲穿的程序猿6 天前
读取芯片内部温度传感器
嵌入式硬件·rust