-
Notifications
You must be signed in to change notification settings - Fork 37
Improve helix::client_ext helpers & types in collections #359
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
Conversation
src/helix/client/client_ext.rs
Outdated
) -> impl futures::Stream<Item = Result<helix::streams::Stream, ClientError<C>>> | ||
+ Send | ||
+ Unpin | ||
+ 'client | ||
where | ||
T: TwitchToken + Send + Sync + ?Sized, | ||
{ | ||
use futures::StreamExt; | ||
futures::stream::iter(ids.chunks(100).map(move |c| { | ||
let req = helix::streams::GetStreamsRequest::user_ids(c).first(100); | ||
make_stream(req, token, self, std::collections::VecDeque::from) | ||
})) | ||
.flatten_unordered(None) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like this construct, maybe we can use it for the other calls as well, to make it possible to query as many things as possible.
Should probably move away from returning a impl Stream
then, and instead return a TwitchResults<T>
or similar which implements it, which we can also use to capture the token better (I think?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or, we should just hint to the user; "this is a way to query more, do it this way"
src/helix/client/client_ext.rs
Outdated
pub fn get_streams_from_ids<T>( | ||
&'client self, | ||
ids: &'client [&'client types::UserIdRef], | ||
token: &'client T, | ||
) -> impl futures::Stream<Item = Result<helix::streams::Stream, ClientError<C>>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hate it
I want the lifetime to be more explicit, should figure out what the correct bound is (if this is not maximally permissable, which I suspect it isn't)
It's good to include more helpers, esp. for easy pagination. Seems like we only need to adjust the example: diff --git a/examples/followed_streams.rs b/examples/followed_streams.rs
index d702260109..b423dfa66c 100644
--- a/examples/followed_streams.rs
+++ b/examples/followed_streams.rs
@@ -1,6 +1,9 @@
+use std::collections::HashMap;
+
use futures::TryStreamExt;
-use twitch_api::helix::HelixClient;
+use twitch_api::helix::{games::get_games::Game, HelixClient};
use twitch_oauth2::{AccessToken, UserToken};
+use twitch_types::CategoryId;
fn main() {
use std::error::Error;
@@ -36,7 +39,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>>
.get_followed_streams(&token)
.try_collect::<Vec<_>>()
.await?;
- let games = client
+ let games: HashMap<CategoryId, Game> = client
.get_games_by_id(
&streams
.iter()
@@ -44,6 +47,8 @@ async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>>
.collect::<Vec<_>>(),
&token,
)
+ .map_ok(|game| (game.id.clone(), game))
+ .try_collect()
.await?;
println!( |
This comment was marked as resolved.
This comment was marked as resolved.
I have some unpushed changes to this branch incorporating twitch-rs/twitch_types#55, I'll clean it up and push for a review |
7ecd9cd
to
af46a86
Compare
i've pushed the changes |
src/helix/client/client_ext.rs
Outdated
/// let users: Vec<helix::users::User> = client | ||
/// .get_users_from_ids(&["1234", "4321"][..].into(), &token).try_collect().await?; | ||
/// # Ok(()) } | ||
/// ``` | ||
pub fn get_users_from_ids<T>( | ||
&'client self, | ||
ids: impl AsRef<[&types::UserIdRef]> + Send, | ||
token: &T, | ||
) -> Result<Option<helix::users::User>, ClientError<C>> | ||
ids: &'client types::Collection<'client, types::UserId>, | ||
token: &'client T, | ||
) -> impl futures::Stream<Item = Result<helix::users::User, ClientError<C>>> + Send + Unpin + 'client | ||
where | ||
T: TwitchToken + Send + Sync + ?Sized, | ||
{ | ||
let ids = ids.as_ref(); | ||
if ids.len() > 100 { | ||
return Err(ClientRequestError::Custom("too many IDs, max 100".into())); | ||
} | ||
self.req_get(helix::users::GetUsersRequest::ids(ids), token) | ||
.await | ||
.map(|response| response.first()) | ||
futures::stream::iter(ids.chunks(100).collect::<Vec<_>>()) | ||
.map(move |c| { | ||
let req = helix::users::GetUsersRequest::ids(c); | ||
futures::stream::once(self.req_get(req, token)).boxed() | ||
}) | ||
.flatten_unordered(None) | ||
.map_ok(|resp| futures::stream::iter(resp.data.into_iter().map(Ok))) | ||
.try_flatten_unordered(None) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like how the examples have to use [..]
I also tried to make the helper functions take impl Into<Collection<'_, T>>
but it didn't work. Still going to try to make it work but I suspect we need some the changes made in 2024 edition for lifetime captures behind impls, or we go the TwitchResult
route. I suspect the TwitchResult
route is what is needed for doing minimal allocations also
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's really only an issue with arrays, no? In real-world code, this would probably be a Vec
or a slice already. But I agree that it makes the examples a bit complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some copy-paste artifacts.
final check wanted, think we can merge this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just documentation stuff. For the wrapping, I put four spaces indentation, but three spaces might look better in the docs.
Co-authored-by: nerix <[email protected]>
62216d0
to
788c4ea
Compare
No description provided.