attrsets

Crates.ioattrsets
lib.rsattrsets
version0.1.2
sourcesrc
created_at2020-07-12 13:38:29.137187
updated_at2022-10-01 23:09:31.816234
descriptionProc macro for defining multiple variants of a struct/enum with different attribute annotations e.g. for multiple Serde serializations
homepagehttps://codeberg.org/valpackett/attrsets
repositoryhttps://codeberg.org/valpackett/attrsets
max_upload_size
id264382
size12,425
Val Packett (valpackett)

documentation

README

crates.io API Docs unlicense

attrsets

Have you ever wanted to, say, define a few different serde serializations for the same structures?

Well, you could always write two versions of a struct, and std::mem::transmute between them to get different serializations:

#[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>,
}

But that's unmaintainable! >_<

This procedural macro automates this process:

#[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>,
}

This example would basically expand into the above.

Every identifier in the attrsets attribute defines a suffix for a new version of the struct. The attrset field attribute wraps any other attribute, only including it in the provided list of variants (comma separated). Use _ for the plain non-suffixed variant e.g.:

#[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>,
}

Limitations

  • errors are not nice
  • no way to propagate the variant choices to nested structs yet
    • of course you can just parameterize the structs and define nice aliases like type PostR = PostReadable<ImageReadable<GeoReadable>>

License

This is free and unencumbered software released into the public domain.
For more information, please refer to the UNLICENSE file or unlicense.org.

Commit count: 0

cargo fmt