tamasfe/aide

`TransformOperation` can't be used in manual `OperationInput` or `OperationOutput` implementations

Opened this issue · 1 comments

lffg commented

Let's suppose one has a common Auth axum extractor which is responsible for authorizing incoming requests, returning 401 responses in case of error. Assuming that, for some reason the OperationOutput needs to be manual (and not generated by the OperationIo macro), one possible implementation would be to:

impl OperationInput for Auth {
    fn operation_input(ctx: &mut GenContext, operation: &mut Operation) {
        let t = TransformOperation::new(operation);
        _ = t.response::<401, http::Error>();
    }
}

Notice that, to reduce boilerplate code and leverage all existing TransformOperation convenience methods (which also provides some error checking under the hood), the implementation wraps the &mut Operation over an TransformOperation.

However, that wouldn't work. When executing the program, the following panic is raised:

already borrowed: BorrowMutError

The errors happens due to the fact that, when aide invokes the operation_input method, it mutably borrows the GEN_CTX thread local, keeping a reference until after such a method finishes. Then, inside operation_input, while the former borrow is still alive, the TransformOperation::response method also tries to borrow it, resulting in a panic.

I don't think if TransformOperation is intended for such manual implementation use cases. However, I really think it should, as it allows for a much nicer and robust interface.

I am opening this issue to try to think about options to solve this issue. See, if operation_input gets a &mut Operation, it would make sense to make one able to create a OperationTransformer over it, right?

A viable option I see is to create a new transformer, OperationTransformerWithCtx, which could be created with both &mut GenContext and &mut Operation. Since it would be more general, to avoid duplication, the current OperationTransformer could be internally reimplemented to use its with ctx counterpart.

WDYT?

I'm also running into this issue and have not found a workaround. Manually editing the operation does not seem very efficient, so it would be nice if this was supported.