Imagine, you need to use the following API to find the most upvoted comment under a blog post.
```rust struct GetCommentsRequest { blogpostid: BlogPostId, page_number: u32, }
struct GetCommentsResponse {
comments: Vec
#
```
In order to do that you will need to write a hairy loop that checks the
more_comments_available
flag, increments page_number
, and updates a
variable that stores the resulting value. This crate helps to abstract away any
sort of pagination and allows you to work with such APIs uniformly with the
help of async streams. All you need to do is to implement the [PageTurner
]
trait instead for the client that sends GetCommentsRequest
.
In [PageTurner
] you specify what items you query and what errors may occur,
then you implement the turn_page
method where you describe how to query a
single page and how to prepare a request for the next page.
```rust use asynctrait::asynctrait; use page_turner::prelude::*;
impl PageTurner
async fn turn_page(&self, mut request: GetCommentsRequest) -> PageTurnerOutput<Self, GetCommentsRequest> {
let response = self.get_comments(request.clone()).await?;
if response.more_comments_available {
request.page_number += 1;
Ok(TurnedPage::next(response.comments, request))
} else {
Ok(TurnedPage::last(response.comments))
}
}
}
#
```
The [PageTurner
] then provides default implementations for pages
and
into_pages
methods that you can use to get a stream of pages and, optionally,
to turn it into a stream of items if you need. Now we can use our client to find
the most upvoted comment like that:
```rust
#
#
#
#
#
#
#
#
#
#
# #
#
let client = OurBlogClient::new();
let mostupvotedcomment = client
.pages(GetCommentsRequest { blogpostid, pagenumber: 1 })
.items()
.tryfold(None::
assert_eq!(most_upvoted_comment.text, "Yeet");
assert_eq!(most_upvoted_comment.upvotes, 5);
// Or we can process the whole pages if needed
let mut comment_pages = client.pages(GetCommentsRequest { blog_post_id, page_number: 1 });
while let Some(comment_page) = comment_pages.try_next().await? {
detect_spam(comment_page);
}
#
```
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.