【ISO8601库】Serde 集成模块详解(serde.rs文件)

概述

这个模块为 ISO8601 日期时间类型提供了 Serde 序列化和反序列化支持,使其能够与 JSON 等格式无缝集成。

模块结构

模块分为四个子模块,分别处理不同的 ISO8601 类型:

  • date - 日期序列化
  • time - 时间序列化
  • datetime - 日期时间序列化
  • duration - 时间段序列化

核心实现模式

1. 序列化实现 (Serialize)

rust 复制代码
impl Serialize for crate::Date {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

工作原理

  • 调用类型的 to_string() 方法转换为 ISO8601 字符串
  • 使用序列化器的 serialize_str() 方法输出字符串

2. 反序列化实现 (Deserialize)

rust 复制代码
impl<'de> Deserialize<'de> for crate::Date {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_str(DateVisitor)
    }
}

工作原理

  • 委托给自定义的 Visitor 处理字符串反序列化
  • 使用 deserialize_str() 方法处理字符串输入

3. Visitor 模式

rust 复制代码
struct DateVisitor;
impl<'de> Visitor<'de> for DateVisitor {
    type Value = crate::Date;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "a string that follows iso8601 date format")
    }

    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        match Self::Value::from_str(s) {
            Ok(p) => Ok(p),
            Err(_) => Err(de::Error::invalid_value(de::Unexpected::Str(s), &self)),
        }
    }
}

Visitor 职责

  • expecting(): 提供错误消息中显示的类型期望描述
  • visit_str(): 实际处理字符串解析,使用类型的 from_str 方法

各类型具体实现

Date 类型 (日期)

格式 : "2023-02-10"

  • 序列化:日期 → "2023-02-10"
  • 反序列化:"2023-02-10" → 日期对象

Time 类型 (时间)

格式 : "18:12:15""18:12:15.0+00:00"

  • 支持带时区和毫秒的扩展格式
  • 测试显示支持简化和完整格式

DateTime 类型 (日期时间)

格式 : "2023-02-10T18:12:15""2023-02-10T18:12:15.0+00:00"

  • 支持多种精度级别
  • 测试验证了完整格式和简化格式(无秒数)

Duration 类型 (时间段)

格式 : "P1Y2M3DT4H5M6S" (ISO8601 持续时间格式)

  • P 表示周期开始
  • Y 年, M 月, D
  • T 时间部分开始
  • H 小时, M 分钟, S

错误处理

反序列化错误

rust 复制代码
Err(de::Error::invalid_value(de::Unexpected::Str(s), &self))

from_str 解析失败时,返回标准的 Serde 错误:

  • invalid_value: 表示输入值无效
  • de::Unexpected::Str(s): 包装实际输入值
  • &self: 提供期望的类型信息(通过 expecting 方法)

测试验证

每个子模块都包含完整的序列化往返测试:

序列化测试

rust 复制代码
#[test]
fn serialize() {
    let date_json = r#""2023-02-10""#;
    let date = crate::date("2023-02-10").unwrap();
    let serialized_date = serde_json::to_string(&date).unwrap();
    assert_eq!(serialized_date, date_json);
}

反序列化测试

rust 复制代码
#[test]
fn deserialize() {
    let date_json = r#""2023-02-10""#;
    let date = crate::date("2023-02-10").unwrap();
    let deserialized_date = serde_json::from_str::<crate::Date>(date_json).unwrap();
    assert_eq!(deserialized_date, date);
}

设计特点

  1. 字符串为基础: 所有类型都序列化为人类可读的 ISO8601 字符串
  2. 格式保持: 序列化后的格式符合 ISO8601 标准
  3. 错误友好: 提供清晰的错误信息和类型期望
  4. 往返安全: 序列化后再反序列化能得到原始对象
  5. 格式灵活性: 支持 ISO8601 的各种格式变体

使用示例

json 复制代码
{
  "date": "2023-02-10",
  "time": "18:12:15", 
  "datetime": "2023-02-10T18:12:15",
  "duration": "P1Y2M3DT4H5M6S"
}
相关推荐
微小冷14 小时前
Rust异步编程详解
开发语言·rust·async·await·异步编程·tokio
鸿乃江边鸟14 小时前
Spark Datafusion Comet 向量化Rust Native--CometShuffleExchangeExec怎么控制读写
大数据·rust·spark·native
明飞19871 天前
tauri
rust
咚为1 天前
Rust tokio:Task ≠ Thread:Tokio 调度模型中的“假并发”与真实代价
开发语言·后端·rust
天天进步20152 天前
Motia性能进阶与未来:从现有源码推测 Rust 重构之路
开发语言·重构·rust
Hello.Reader3 天前
Rocket 0.5 响应体系Responder、流式输出、WebSocket 与 uri! 类型安全 URI
websocket·网络协议·安全·rust·rocket
FreeBuf_3 天前
黑客利用React Native CLI漏洞(CVE-2025-11953)在公开披露前部署Rust恶意软件
react native·react.js·rust
鸿乃江边鸟3 天前
Spark Datafusion Comet 向量化Rust Native--Native算子(CometNativeExec)怎么串联执行
大数据·rust·spark·native
mit6.8243 天前
[]try catch no | result yes
rust
Ivanqhz3 天前
向量化计算
开发语言·c++·后端·算法·支持向量机·rust