-
-
Notifications
You must be signed in to change notification settings - Fork 277
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
Add a Page::all
method
#423
Comments
Thank you for your issue! While I can appreciate the ergonomics of that, it would require that all pages keep a reference to the HTTP client which would bring a cost, and I don't want to add a hidden cost for just one method. The best we could do is maybe the following, but I'd have to check if the borrow checker allows it. impl Page<T> {
async fn all(self, crab: &Octocrab) -> Vec<T> {
crab.all_pages(self).await
}
} let issues = crab.issues()
...
.await?
.all(&crab)
.await?; |
You could just do something like this, right? impl Page<T> {
async fn all(self, crab: &Octocrab) -> Vec<T> {
crate::instance().all_pages(self).await
}
} That would require the user to set the global instance, but I think adding a note about it using the global instance would be sufficient. I know there's a bit of flexibility lost, but considering there wouldn't be any parameter stuff to deal with then I think it'd be best.
The way I'd personally want the API is to not have to think about passing in an What do you think? |
Are you talking about a maintenance cost or some kind of runtime cost? I wouldn't think the maintenance part would be too much of an issue since you're just adding an extra field to the struct, right? |
I don't think that's intuitive that this one method requires the global instance, that's not worth it for saving one parameter.
Runtime and borrowing cost, adding an extra field makes the page bigger, and it will affect the lifetime of the |
I suppose it'd be bigger, but I'd think quite negligible since it's just storing a reference to another object. Considering everything else that gets created in a normal program's lifespan I'd think that the space wouldn't make much of a difference in anything. I don't think the lifetime stuff should be much of an issue, as all the |
Handler's are designed to be short lived, they're only supposed to exist for the length it takes you to set the arguments and then send the request. The data that's returned is expected to live much longer, and may be sent across threads where adding a reference would make that not possible. |
IMO, the library should handle returning the complete results. One page is not super useful, especially when there are no helper methods to continue through the paged results. I tried implementing a stream over paged results, but couldn't get past the methods that consume self... pub trait GetAllPages<T> {
async fn get_all_pages(self) -> octocrab::Result<Vec<T>>;
}
impl<'octo, 'r> GetAllPages<Label> for ListLabelsForRepoBuilder<'octo, 'r> {
async fn get_all_pages(self) -> octocrab::Result<Vec<Label>> {
use futures::stream::{self, TryStreamExt};
let stream = stream::try_unfold(1u32, |page_number| async move {
// this doesn't work because page() and send() take ownership of self
// but self is needed by the subsequent calls to this FnMut closure
let result = self.page(page_number).send().await?;
if result.next.is_some() {
let next_page_number = page_number + 1;
let yielded = result.items;
Ok(Some((yielded, next_page_number)))
} else {
Ok(None)
}
});
// might be able to try_flatten and try_collect without the match
let labels: octocrab::Result<Vec<Vec<Label>>> = stream.try_collect().await;
let labels = match labels {
Ok(labels) => Ok(labels.into_iter().flatten().collect()),
Err(e) => return Err(e),
};
labels
}
} |
I take back my previous comment. I have just revisited this and noticed the https://docs.rs/octocrab/0.39.0/octocrab/struct.Page.html#method.into_stream |
Would it be possible to add a function such as
Page::all
that just does something likeOctocrab::all_pages(page)
? Currently I have to make an intermediate variable when doing something like this to fetch all issues:Having a
Page::all
method would make the code feel a lot cleaner imo, as you don't have that intermediate variable:The text was updated successfully, but these errors were encountered: