Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implementation of twitch_oauth2::client::Client is not general enough #236

Closed
Fr33maan opened this issue Dec 13, 2021 · 7 comments · Fixed by #303
Closed

implementation of twitch_oauth2::client::Client is not general enough #236

Fr33maan opened this issue Dec 13, 2021 · 7 comments · Fixed by #303
Assignees

Comments

@Fr33maan
Copy link

I'm trying to use the client in a tokio::spawn context but I get the following error.

async fn get_auth_token_request() -> Result<AppAccessToken, AppError> {
    let config = get_config();

    let client_id = ClientId::new(config.twitch.api.id.clone());
    let client_secret = ClientSecret::new(config.twitch.api.secret.clone());
    let client: TwitchClient<reqwest::Client> = TwitchClient::default();

    let token =
        AppAccessToken::get_app_access_token(&client, client_id, client_secret, Scope::all())
            .await
            .unwrap();

    Ok(token)
}

fn spawn_followers_poll(pool: Pool) {
    tokio::spawn({ // <---- here is the error
        async move {
            get_auth_token_request().await.unwrap();
        }
    });
}
implementation of `twitch_oauth2::client::Client` is not general enough
`twitch_oauth2::client::Client<'1>` would have to be implemented for the type `TwitchClient<'0, reqwest::Client>`, for any two lifetimes `'0` and `'1`...
...but `twitch_oauth2::client::Client<'2>` is actually implemented for the type `TwitchClient<'2, reqwest::Client>`, for some specific lifetime `'2`rustc

Following the exemple, I can see that we must explicit some lifetimes but I don't really understand what should be done.

Can you provide some help please ?

@Emilgardis Emilgardis self-assigned this Dec 13, 2021
@Emilgardis

This comment has been minimized.

@Emilgardis
Copy link
Member

Emilgardis commented Dec 13, 2021

scratch that, that's not the error...

minimal repro:

use twitch_api2::{twitch_oauth2::*, *};

async fn get_auth_token_request(client: &TwitchClient<'static, reqwest::Client>) -> Result<AppAccessToken, ()> {

    let client_id = ClientId::new("aaa");
    let client_secret = ClientSecret::new("aaaa");

    let token =
        AppAccessToken::get_app_access_token(client, client_id, client_secret, Scope::all())
            .await
            .unwrap();

    Ok(token)
}

fn spawn_followers_poll() {
    let client: TwitchClient<'static, reqwest::Client> = TwitchClient::new();

    tokio::spawn({
        // <---- here is the error
        async move {
            get_auth_token_request(&client).await.unwrap();
        }
    });
}

pub fn main() {

}

gives

error: implementation of `twitch_api2::twitch_oauth2::client::Client` is not general enough
  --> examples\waaah.rs:19:5
   |
19 |     tokio::spawn({
   |     ^^^^^^^^^^^^ implementation of `twitch_api2::twitch_oauth2::client::Client` is not general enough
   |
   = note: `twitch_api2::twitch_oauth2::client::Client<'1>` would have to be implemented for the type `twitch_api2::TwitchClient<'0, reqwest::Client>`, for any two lifetimes `'0` and `'1`...
   = note: ...but `twitch_api2::twitch_oauth2::client::Client<'2>` is actually implemented for the type `twitch_api2::TwitchClient<'2, reqwest::Client>`, for some specific lifetime `'2`

error: could not compile `twitch_api2` due to previous error

I'm not sure if this is a library issue, or if it's a rust bug.

@Emilgardis
Copy link
Member

cc rust-lang/rust#85516

@Emilgardis
Copy link
Member

Emilgardis commented Dec 13, 2021

I'm not 100% sure what this issue is, but to fix it there is a workaround.

Instead of giving the TwitchClient, give it the "real" client inside, this can be done with client.helix.clone_client()

so

AppAccessToken::get_app_access_token(&client.helix.clone_client(), ...)

I'm going to expose the client() fn to make this easier and not having to clone (although the clone is cheap). So it would become client.get_client() instead.

I need to do some minimization of this to see if this is the same as above mentioned issue or if it's something else.

Emilgardis added a commit that referenced this issue Dec 13, 2021
Emilgardis added a commit that referenced this issue Dec 13, 2021
bors bot added a commit that referenced this issue Dec 13, 2021
237: expose a way to get a reference to HttpClient r=Emilgardis a=Emilgardis

touches on #236


Co-authored-by: Emil Gardström <emil.gardstrom@gmail.com>
Emilgardis added a commit that referenced this issue Dec 13, 2021
bors bot added a commit that referenced this issue Dec 13, 2021
237: expose a way to get a reference to HttpClient r=Emilgardis a=Emilgardis

touches on #236


Co-authored-by: Emil Gardström <emil.gardstrom@gmail.com>
@Fr33maan
Copy link
Author

Thanks ! I tried to implement the given solution like this:

async fn get_auth_token_request(config: &Config) -> Result<AppAccessToken, AppError> {
    let client_id = ClientId::new(config.twitch.api.id.clone());
    let client_secret = ClientSecret::new(config.twitch.api.secret.clone());
    let client: TwitchClient<'static, reqwest::Client> = TwitchClient::new();

    let token = AppAccessToken::get_app_access_token(  // <------ error here
        &client.helix.clone_client(),
        client_id,
        client_secret,
        Scope::all(),
    )
    .await
    .unwrap();

    Ok(token)
}

This brings the following issue:

the trait bound `reqwest::Client: twitch_oauth2::client::Client<'_>` is not satisfied
the trait `twitch_oauth2::client::Client<'_>` is not implemented for `reqwest::Client`rustcE0277
app_access_token.rs(136, 12): required by a bound in `twitch_oauth2::AppAccessToken::get_app_access_token`

Then I tried to replace the reqwest client with the twitch_oauth2 one, even if I'm not sure why I'm required too.

async fn get_auth_token_request(config: &Config) -> Result<AppAccessToken, AppError> {
    let client_id = ClientId::new(config.twitch.api.id.clone());
    let client_secret = ClientSecret::new(config.twitch.api.secret.clone());
    let client: TwitchClient<'static, dyn twitch_oauth2::client::Client> = TwitchClient::new(); // <----- error 1 here (I tried with and without dyn keyword)

    let token = AppAccessToken::get_app_access_token(
        &client.helix.clone_client(),  // <-----  error 2 here
        client_id,
        client_secret,
        Scope::all(),
    )
    .await
    .unwrap();

    Ok(token)
}
the size for values of type `dyn twitch_oauth2::client::Client<'_>` cannot be known at compilation time
the trait `Sized` is not implemented for `dyn twitch_oauth2::client::Client<'_>`rustcE0277
lib.rs(203, 29): required by a bound in `TwitchClient`
the method `clone_client` exists for struct `HelixClient<'static, dyn twitch_oauth2::client::Client<'_>>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`dyn twitch_oauth2::client::Client<'_>: Sized`
`dyn twitch_oauth2::client::Client<'_>: HttpClient`rustcE0599
client.rs(17, 1): doesn't satisfy `dyn twitch_oauth2::client::Client<'_>: HttpClient`
client.rs(17, 1): doesn't satisfy `dyn twitch_oauth2::client::Client<'_>: Sized`

@Emilgardis
Copy link
Member

Second way wont work. the error message after doing the workaround suggests that you dont have reqwest_client feature enabled in twitch_api2.

bors bot added a commit that referenced this issue Dec 19, 2022
303: fix lifetimes issues r=Emilgardis a=Emilgardis

resolves #236 

Co-authored-by: Emil Gardström <emil.gardstrom@gmail.com>
@bors bors bot closed this as completed in b4fe612 Dec 19, 2022
@Emilgardis
Copy link
Member

this just works™️ now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants