I have an implementation for a struct that needs to be implemented on multiple structs with an argument for every struct.
My impl statement is as follows:
#[rocket::async_trait]
impl<'r> FromRequest<'r> for ReadMe {
type Error = AuthErrors;
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
let db = request
.guard::<&State<mongodb::Database>>()
.await
.expect("No database state!");
let token = request.headers().get_one("Authorization");
match token {
Some(token) => {
// check validity
let user = get_user_by_token(token.to_string(), db.inner().to_owned()).await;
match user {
Some(user) => {
if user.tokenData.scopes.split(" ").any(|x| x == "ReadMe") {
Outcome::Success(ReadMe(Some(BasicScope {
user: user.user,
value: true,
})))
} else {
Outcome::Failure((Status::Forbidden, AuthErrors::ScopeMissing))
}
}
None => Outcome::Failure((Status::Unauthorized, AuthErrors::Invalid)), // TODO?: Should this return something else?
}
}
None => Outcome::Failure((Status::Unauthorized, AuthErrors::Missing)),
}
}
}
The reason this would benefit from being a macro is that I will have a lot of structs that need a slightly modified version of that implementation ("ReadMe"
has to be different for every struct). Instead of copy and pasting this implementation, each one being slightly modified it would be cleaner to do #[derive(Scope("ReadMe"))]
.
How could this be transformed in to a macro I can reuse?