#variant #proc-macro-attributes #attributes #serde #proc-macro #cloning

attrsets

用于定义具有不同属性注解的结构体/枚举的多个变体的过程宏,例如用于多个Serde序列化

3个版本

0.1.2 2022年10月1日
0.1.1 2022年8月1日
0.1.0 2020年7月12日

编码 中排名 1211

每月下载量 39

Unlicense

12KB
180

crates.io API Docs unlicense

attrsets

你是否曾经想要定义针对相同结构的几个不同 序列化

嗯,你总是可以写两个结构体的版本,并在它们之间使用 std::mem::transmute 来获取不同的序列化

#[derive(Deserialize, Serialize)]
pub struct Thing {
    pub flag: bool,
    pub time: DateTime<Utc>,
}

#[derive(Deserialize, Serialize)]
pub struct ThingCompact {
    #[serde(rename = "f")]
    pub flag: bool,

    #[serde(with = "ts_seconds")]
    #[serde(rename = "t")]
    pub time: DateTime<Utc>,
}

但这是不可维护的!>_<

这个过程宏自动化了这个过程

#[attrsets::attrsets(Compact)]
#[derive(Deserialize, Serialize)]
pub struct Thing {
    #[attrset(Compact, serde(rename = "f"))]
    pub flag: bool,

    #[attrset(Compact, serde(with = "ts_seconds"))]
    #[attrset(Compact, serde(rename = "t"))]
    pub time: DateTime<Utc>,
}

这个示例基本上会扩展到上面。

attrsets 属性中的每个标识符都定义了一个结构体新版本的后缀。 attrset 字段属性包装任何其他属性,只包括在提供的变体列表中(逗号分隔)。使用 _ 表示不带后缀的普通变体,例如。

#[attrsets::attrsets(Readable)]
#[derive(Deserialize, Serialize)]
pub struct Thing {
    #[attrset(_, serde(rename = "f"))]
    pub flag: bool,

    #[attrset(_, serde(with = "ts_seconds"))]
    #[attrset(_, serde(rename = "t"))]
    pub time: DateTime<Utc>,
}

限制

  • 错误不是很友好
  • 还不能将变体选择传播到嵌套结构体中
    • 当然,你可以通过参数化结构体并定义如 type PostR = PostReadable<ImageReadable<GeoReadable>> 这样的好别名

许可证

这是一个免费且不受限制的软件,已发布到公有领域。
有关更多信息,请参阅 UNLICENSE 文件或 unlicense.org

依赖

~2MB
~43K SLoC