Azure / azure-sdk-for-rust

This repository is for active development of the *unofficial* Azure SDK for Rust. This repository is *not* supported by the Azure SDK team.
MIT License
692 stars 237 forks source link

Add a derive macro to simplify implementing `Model` #1765

Open analogrelay opened 2 weeks ago

analogrelay commented 2 weeks ago

In #1724 , I introduce the Model trait, and json_model!/xml_model! macros for implementing that trait via Deserialize. In that PR, we identified that a derive macro would be a much smoother way to do this. For example, instead of the current code:

#[derive(Deserialize)]
pub struct GetSecretResponse {
    name: String,
    value: String,
}
json_model!(GetSecretResponse);

We could write:

#[derive(Model, Deserialize)]
#[typespec(format = "json")] // This would actually be the default, but other formats like 'xml' would be supported
pub struct GetSecretResponse {
    name: String,
    value: String
}

This macro should live in a typespec_derive crate. One minor challenge is that since this at the TypeSpec level, not the Azure SDK level, it will be generating an impl for typespec_client_core::http::Model. That means that clients that use this macro need to take a dependency directly on that crate, even if they get it already through azure_core. I'm not a huge fan of that, but it's fairly common problem. For example, I believe you need to directly reference serde in order to derive Deserialize, even if you have access to the trait through a re-export. It's possible to make the crate from which Model is reference parameterizable (like how serde does with the crate attribute) but that's not really better, since it would require clients to explicitly fill it in:

#[derive(Model, Deserialize)]
#[typespec(crate = "azure_core")]
pub struct GetSecretResponse {
    name: String,
    value: String
}

I don't think that's better. It's possible we could do something in an azure_derive crate to "wrap" the macro in typespec_derive and set the crate, but again that feels kinda messy and results in two separate derive macros.

analogrelay commented 2 weeks ago

I can't assign this or set labels because I don't have write permissions, but I'm working on this right now and expect to submit a PR. It's a follow-up work item from comments on #1724