implementation of `twitch_oauth2::client::Client` is not general enough
Fr33maan opened this issue · 7 comments
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 ?
real error is
/// [dependencies]
/// twitch_api2 = {version= "0.6.0-rc.3", features = ["client", "helix", "reqwest_client"]}
/// tokio = {version = "*", features=["full"]}
/// reqwest = "*"
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();
}
});
}
❯ cargo check
Checking aaa v0.1.0 (G:\workspace\small dev space\aaa)
error[E0277]: the trait bound `&twitch_api2::TwitchClient<'_, reqwest::Client>: twitch_api2::twitch_oauth2::client::Client<'_>` is not satisfied
--> src\lib.rs:9:9
|
9 | AppAccessToken::get_app_access_token(&client, client_id, client_secret, Scope::all())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `twitch_api2::twitch_oauth2::client::Client<'_>` is not implemented for `&twitch_api2::TwitchClient<'_, reqwest::Client>`
|
= help: the following implementations were found:
<twitch_api2::TwitchClient<'a, C> as twitch_api2::twitch_oauth2::client::Client<'a>>
note: required by a bound in `twitch_api2::twitch_oauth2::AppAccessToken::get_app_access_token`
--> G:\workspace\twitch_api2\twitch_oauth2\src\tokens\app_access_token.rs:136:12
p_access_token`
error[E0277]: the trait bound `&twitch_api2::TwitchClient<'_, reqwest::Client>: twitch_api2::twitch_oauth2::client::Client<'_>` is not satisfied
--> src\lib.rs:9:9
|
9 | / AppAccessToken::get_app_access_token(&client, client_id, client_secret, Scope::all())
10 | | .await
| |__________________^ the trait `twitch_api2::twitch_oauth2::client::Client<'_>` is not implemented for `&twitch_api2::TwitchClient<'_, reqwest::Client>`
|
= help: the following implementations were found:
<twitch_api2::TwitchClient<'a, C> as twitch_api2::twitch_oauth2::client::Client<'a>>
For more information about this error, try `rustc --explain E0277`.
error: could not compile `aaa` due to 2 previous errors
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.
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.
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`
Second way wont work. the error message after doing the workaround suggests that you dont have reqwest_client
feature enabled in twitch_api2
.
this just works™️ now