mirror of
https://github.com/System-End/slack-morphism-rust.git
synced 2026-04-19 14:17:02 +00:00
feat: Adapt internal SlackApiScrollableResponse API for more flexible paging (#344)
* feat: Adapt internal SlackApiScrollableResponse API for more flexible paging * chore: Examples update
This commit is contained in:
parent
af8708f2e7
commit
a92ec21d4a
6 changed files with 84 additions and 15 deletions
|
|
@ -117,6 +117,26 @@ async fn test_file_upload() -> Result<(), Box<dyn std::error::Error + Send + Syn
|
|||
&complete_file_upload_resp
|
||||
);
|
||||
|
||||
let all_channels_scroller = SlackApiConversationsListRequest::new().scroller();
|
||||
let channels: Vec<SlackChannelInfo> = all_channels_scroller
|
||||
.collect_items_stream(&session, Duration::from_millis(1000))
|
||||
.await?;
|
||||
println!("Number of channels: {:#?}", channels.len());
|
||||
|
||||
if let Some(general_channel_info) = channels
|
||||
.into_iter()
|
||||
.find(|c| c.flags.is_general.unwrap_or(false))
|
||||
{
|
||||
println!("General channel info: {:#?}", general_channel_info);
|
||||
let files_list_scroller = SlackApiFilesListRequest::new()
|
||||
.with_channel(general_channel_info.id)
|
||||
.scroller();
|
||||
let files: Vec<SlackFile> = files_list_scroller
|
||||
.collect_items_stream(&session, Duration::from_millis(1000))
|
||||
.await?;
|
||||
println!("Number of files in general: {:#?}", files.len());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -453,10 +453,11 @@ impl SlackApiScrollableResponse for SlackApiChatScheduledMessagesListResponse {
|
|||
type CursorType = SlackCursorId;
|
||||
type ResponseItemType = SlackApiChatScheduledMessageInfo;
|
||||
|
||||
fn next_cursor(&self) -> Option<&Self::CursorType> {
|
||||
fn next_cursor(&self) -> Option<Self::CursorType> {
|
||||
self.response_metadata
|
||||
.as_ref()
|
||||
.and_then(|rm| rm.next_cursor.as_ref())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
|
||||
|
|
|
|||
|
|
@ -426,10 +426,11 @@ impl SlackApiScrollableResponse for SlackApiConversationsHistoryResponse {
|
|||
type CursorType = SlackCursorId;
|
||||
type ResponseItemType = SlackHistoryMessage;
|
||||
|
||||
fn next_cursor(&self) -> Option<&Self::CursorType> {
|
||||
fn next_cursor(&self) -> Option<Self::CursorType> {
|
||||
self.response_metadata
|
||||
.as_ref()
|
||||
.and_then(|rm| rm.next_cursor.as_ref())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
|
||||
|
|
@ -540,10 +541,11 @@ impl SlackApiScrollableResponse for SlackApiConversationsListResponse {
|
|||
type CursorType = SlackCursorId;
|
||||
type ResponseItemType = SlackChannelInfo;
|
||||
|
||||
fn next_cursor(&self) -> Option<&Self::CursorType> {
|
||||
fn next_cursor(&self) -> Option<Self::CursorType> {
|
||||
self.response_metadata
|
||||
.as_ref()
|
||||
.and_then(|rm| rm.next_cursor.as_ref())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
|
||||
|
|
@ -590,10 +592,11 @@ impl SlackApiScrollableResponse for SlackApiConversationsMembersResponse {
|
|||
type CursorType = SlackCursorId;
|
||||
type ResponseItemType = SlackUserId;
|
||||
|
||||
fn next_cursor(&self) -> Option<&Self::CursorType> {
|
||||
fn next_cursor(&self) -> Option<Self::CursorType> {
|
||||
self.response_metadata
|
||||
.as_ref()
|
||||
.and_then(|rm| rm.next_cursor.as_ref())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
|
||||
|
|
@ -677,10 +680,11 @@ impl SlackApiScrollableResponse for SlackApiConversationsRepliesResponse {
|
|||
type CursorType = SlackCursorId;
|
||||
type ResponseItemType = SlackHistoryMessage;
|
||||
|
||||
fn next_cursor(&self) -> Option<&Self::CursorType> {
|
||||
fn next_cursor(&self) -> Option<Self::CursorType> {
|
||||
self.response_metadata
|
||||
.as_ref()
|
||||
.and_then(|rm| rm.next_cursor.as_ref())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
|
||||
|
|
|
|||
|
|
@ -2,11 +2,6 @@
|
|||
//! Support for Slack Files API methods
|
||||
//!
|
||||
|
||||
use rsb_derive::Builder;
|
||||
use rvstruct::ValueStruct;
|
||||
use serde::{Deserialize, Serialize, Serializer};
|
||||
use serde_with::skip_serializing_none;
|
||||
|
||||
use crate::api::{
|
||||
SlackApiUsersConversationsRequest, SlackApiUsersConversationsResponse,
|
||||
SlackApiUsersProfileSetRequest, SlackApiUsersProfileSetResponse,
|
||||
|
|
@ -14,8 +9,15 @@ use crate::api::{
|
|||
use crate::models::*;
|
||||
use crate::multipart_form::FileMultipartData;
|
||||
use crate::ratectl::*;
|
||||
use crate::SlackClientSession;
|
||||
use crate::{ClientResult, SlackClientHttpConnector};
|
||||
use crate::{SlackApiScrollableRequest, SlackApiScrollableResponse, SlackClientSession};
|
||||
use futures_util::future::BoxFuture;
|
||||
use futures_util::FutureExt;
|
||||
use rsb_derive::Builder;
|
||||
use rvstruct::ValueStruct;
|
||||
use serde::{Deserialize, Serialize, Serializer};
|
||||
use serde_with::skip_serializing_none;
|
||||
use tokio_stream::StreamExt;
|
||||
|
||||
impl<'a, SCHC> SlackClientSession<'a, SCHC>
|
||||
where
|
||||
|
|
@ -223,6 +225,46 @@ pub struct SlackApiFilesListPaging {
|
|||
pub pages: Option<u32>,
|
||||
}
|
||||
|
||||
impl<SCHC> SlackApiScrollableRequest<SCHC> for SlackApiFilesListRequest
|
||||
where
|
||||
SCHC: SlackClientHttpConnector + Send + Sync + Clone + 'static,
|
||||
{
|
||||
type ResponseType = SlackApiFilesListResponse;
|
||||
type CursorType = u32;
|
||||
type ResponseItemType = SlackFile;
|
||||
|
||||
fn with_new_cursor(&self, new_cursor: Option<&Self::CursorType>) -> Self {
|
||||
self.clone().opt_page(new_cursor.cloned())
|
||||
}
|
||||
|
||||
fn scroll<'a, 's>(
|
||||
&'a self,
|
||||
session: &'a SlackClientSession<'s, SCHC>,
|
||||
) -> BoxFuture<'a, ClientResult<Self::ResponseType>> {
|
||||
async move { session.files_list(self).await }.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl SlackApiScrollableResponse for SlackApiFilesListResponse {
|
||||
type CursorType = u32;
|
||||
type ResponseItemType = SlackFile;
|
||||
|
||||
fn next_cursor(&self) -> Option<Self::CursorType> {
|
||||
self.paging
|
||||
.as_ref()
|
||||
.into_iter()
|
||||
.filter_map(|paging| match (paging.page, paging.pages) {
|
||||
(Some(page), Some(pages)) if page < pages => Some(page + 1),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
|
||||
Box::new(self.files.iter())
|
||||
}
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
|
||||
pub struct SlackApiFilesUploadRequest {
|
||||
|
|
|
|||
|
|
@ -233,10 +233,11 @@ impl SlackApiScrollableResponse for SlackApiUsersConversationsResponse {
|
|||
type CursorType = SlackCursorId;
|
||||
type ResponseItemType = SlackChannelInfo;
|
||||
|
||||
fn next_cursor(&self) -> Option<&Self::CursorType> {
|
||||
fn next_cursor(&self) -> Option<Self::CursorType> {
|
||||
self.response_metadata
|
||||
.as_ref()
|
||||
.and_then(|rm| rm.next_cursor.as_ref())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
|
||||
|
|
@ -284,10 +285,11 @@ impl SlackApiScrollableResponse for SlackApiUsersListResponse {
|
|||
type CursorType = SlackCursorId;
|
||||
type ResponseItemType = SlackUser;
|
||||
|
||||
fn next_cursor(&self) -> Option<&Self::CursorType> {
|
||||
fn next_cursor(&self) -> Option<Self::CursorType> {
|
||||
self.response_metadata
|
||||
.as_ref()
|
||||
.and_then(|rm| rm.next_cursor.as_ref())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ pub trait SlackApiScrollableResponse {
|
|||
type CursorType;
|
||||
type ResponseItemType;
|
||||
|
||||
fn next_cursor(&self) -> Option<&Self::CursorType>;
|
||||
fn next_cursor(&self) -> Option<Self::CursorType>;
|
||||
fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a>;
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ where
|
|||
.scroll(session)
|
||||
.map_ok(|res| {
|
||||
self.last_response = Some(res.clone());
|
||||
self.last_cursor = res.next_cursor().cloned();
|
||||
self.last_cursor = res.next_cursor();
|
||||
res
|
||||
})
|
||||
.await
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue