Mismatch return type: Can I simplify return type?

I'm implementing a function that returns an instance of BasicClient from the oauth2 crate, but I'm encountering a type mismatch error.

Here's the function:

fn create_oauth_client(port: u16) -> Result<BasicClient> {
    // Unimportant code omitted

    let client = BasicClient::new(client_id)
        .set_auth_uri(auth_url)
        .set_token_uri(token_url)
        .set_redirect_uri(RedirectUrl::new(format!("http://localhost:{port}"))?);

    Ok(client)
}

However, this results in the following compilation error:

error[E0308]: mismatched types
   --> src/auth_service.rs:40:8
    |
40  |     Ok(client)
    |     -- ^^^^^^ expected `Client<StandardErrorResponse<...>, ..., ..., ..., ...>`, found `Client<StandardErrorResponse<...>, ..., ..., ..., ..., ..., ..., ..., ..., ...>`
    |     |
    |     arguments to this enum variant are incorrect
    |
    = note: expected struct `oauth2::Client<_, _, _, _, _, EndpointNotSet, _, _, _, EndpointNotSet>`
               found struct `oauth2::Client<_, _, _, _, _, EndpointSet, _, _, _, EndpointSet>`

I know if I specify the exact type of client ( Client<StandardErrorResponse<BasicErrorResponseType>, StandardTokenResponse<EmptyExtraTokenFields, BasicTokenType>, StandardTokenIntrospectionResponse<EmptyExtraTokenFields, BasicTokenType>, StandardRevocableToken, StandardErrorResponse<RevocationErrorResponseType>, EndpointSet, EndpointNotSet, EndpointNotSet, EndpointNotSet, EndpointSet>), the error goes away, but the type is quite long, which hurts readability.
Is it possible to simplify the return type?

I would define a type alias for the specific variation you are using.

type Client = oauth2::Client<StandardErrorResponse<BasicErrorResponseType>, StandardTokenResponse<EmptyExtraTokenFields, BasicTokenType>, StandardTokenIntrospectionResponse<EmptyExtraTokenFields, BasicTokenType>, StandardRevocableToken, StandardErrorResponse<RevocationErrorResponseType>, EndpointSet, EndpointNotSet, EndpointNotSet, EndpointNotSet, EndpointSet>;

fn create_oauth_client(port: u16) -> Result<Client> {
    ...
}

There are other possible solutions in other circumstances (particularly if a trait is involved) but this is the most general one, and it should be clean in the rest of your code unless you need other variations of oauth2::Client too.

2 Likes

Thank you!
I don't need other variations of oauth2::Client, so your suggestion works well.

I am asking for too much but I wonder if there's a macro or some other mechanism that eliminates the need to manually check and specify the type of a variable in the first place.

There is an experimental feature (type_alias_impl_trait) which will allow specifying a type alias as “this is a particular type that implements this trait” without writing out a full specification of the concrete type. However, that does not apply to this situation, because the actual use of oauth2::Client is not through a trait.

Broadly, you always have to give enough information to specify what you can do with the type, and the authors of oauth2::Client have decided to expose a lot of possible variations of what you can do.

2 Likes

you always have to give enough information to specify what you can do with the type , and the authors of oauth2::Client have decided to expose a lot of possible variations of what you can do.

This really makes sense to me. Thank you.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.