I recently have been working on a medium sized Golang application which is a REST web application, backed by an ORM over MySQL, JWT for authentication, which uses Swagger via code generation from comments around models and endpoints.
For a much more detailed background, see this stack exchange question which discusses the issue I was running into, which I will summarize now.
I have about 12 database models which map onto database tables, and I'm building the admin API routes and views, something like 56 routes, and something like 88 Swagger structs for providing views on the database models. For a given database model, I have a create model, which includes almost all of the fields except for the id and created/updated timestamps, a read model, which includes almost all of the fields (excluding KDF fields, obviously, for password stuff), an update model where every field is optional (for PATCH) requests, and a delete model for returning the ID and a deleted at timestamp.
Create structs are copied field by field to a database ORM object, read structs are copied from database models field by field, update structs are essentially made of Options and are only copied if they possess a value (only update what has been specified), and delete structs are simple copies from the deleted database model.
The main issue that I have is that there is a ridiculous amount of boilerplate. One update handler is 300 lines of if statements and copying values.
In any case, this brings me to Rust. I have more experience in Rust than Go, and I am seriously missing all of the Rust features like Options and enums, macros, etc. As a result, I am thinking of how I'd deal with the boilerplate in Rust. In Go, my solution was essentially to use reflection at runtime and struct tags to copy from one unrelated struct to another, but obviously runtime reflection in Rust isn't really a thing unless you build it yourself.
In Rust, I imagine to deal with this, I'd probably end up writing procedural macros or something like that to implement some sort of trait like Into or From, except without taking ownership of the source struct. I could probably even do the codegen of the many of the view structs themselves, but there are some mismatches that I don't have a clear sense on how to deal with: an update view for a user can contain a new password, and that field should never map directly onto the database model's password field, which is a byte array of the hashed password.
Has anyone else encountered a similar problem to solve in the wild, and does anyone have any other ideas of how to deal with this problem specific to Rust and its ecosystem?