mutiny_rs/builders/
fetch_messages.rs1use std::collections::HashMap;
2use serde::{Deserialize, Serialize};
3use crate::context::Context;
4use crate::http::HttpError;
5use crate::http::routing::Route;
6use crate::model::message::Message;
7use crate::model::ready::Member;
8use crate::model::user::User;
9
10pub struct FetchMessagesBuilder<'a> {
11 pub(crate) limit: Option<usize>,
12 pub(crate) before: Option<String>,
13 pub(crate) after: Option<String>,
14 pub(crate) sort: Option<Sort>,
15 pub(crate) nearby: Option<String>,
16 pub(crate) include_users: Option<bool>,
17 pub(crate) channel_id: String,
18 pub(crate) ctx: &'a Context,
19}
20#[derive(Serialize)]
21struct FetchMessagesQuery<'a> {
22 #[serde(skip_serializing_if = "Option::is_none")]
23 limit: Option<usize>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 before: Option<&'a str>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 after: Option<&'a str>,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 sort: Option<Sort>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 nearby: Option<&'a str>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 include_users: Option<bool>,
34}
35#[derive(Debug, Clone, Copy, Serialize)]
36pub enum Sort {
37 Relevance,
38 Latest,
39 Oldest,
40}
41#[derive(Debug, Deserialize)]
42pub struct MessageSearchResponse {
43 pub messages: Vec<Message>,
44 #[serde(default)]
45 pub users: Vec<User>,
46 #[serde(default)]
47 pub members: Vec<Member>,
48}
49#[derive(Debug, Deserialize)]
50#[serde(untagged)]
51pub enum MessageFetchResult {
52 MessagesOnly(Vec<Message>),
53 WithUsersAndMembers(MessageSearchResponse),
54}
55impl<'a> FetchMessagesBuilder<'a> {
56 pub fn limit(mut self, limit: usize) -> Self {
57 self.limit = Some(limit);
58 self
59 }
60 pub fn before(mut self, before: impl Into<String>) -> Self {
61 self.before = Some(before.into());
62 self
63 }
64 pub fn after(mut self, after: impl Into<String>) -> Self {
65 self.after = Some(after.into());
66 self
67 }
68 pub fn sort(mut self, sort: Sort) -> Self {
69 self.sort = Some(sort);
70 self
71 }
72 pub fn nearby(mut self, nearby: impl Into<String>) -> Self {
73 self.nearby = Some(nearby.into());
74 self
75 }
76 pub fn include_users(mut self, include_users: bool) -> Self {
77 self.include_users = Some(include_users);
78 self
79 }
80 pub async fn execute(&self) -> Result<Vec<Message>, HttpError> {
81 let query = FetchMessagesQuery {
82 limit: self.limit,
83 before: self.before.as_deref(),
84 after: self.after.as_deref(),
85 sort: self.sort,
86 nearby: self.nearby.as_deref(),
87 include_users: self.include_users,
88 };
89
90 let route = Route::FetchMessages { channel_id: &self.channel_id };
91
92 let result = self.ctx.http.request::<(), FetchMessagesQuery, MessageFetchResult>(route, None, Some(&query)).await?;
93
94 let messages = match result {
95 MessageFetchResult::MessagesOnly(list) => list,
96 MessageFetchResult::WithUsersAndMembers(data) => {
97 let mut messages = data.messages;
98
99 let users_map: HashMap<String, User> = data.users.into_iter()
100 .map(|user| (user.id.clone(), user))
101 .collect();
102
103 let members_map: HashMap<String, Member> = data.members.into_iter()
104 .map(|member| (member._id.user.clone(), member))
105 .collect();
106
107 for message in &mut messages {
108 if let Some(user) = users_map.get(&message.author) {
109 message.user = Some(user.clone());
110 }
111 if let Some(member) = members_map.get(&message.author) {
112 message.member = Some(member.clone());
113 }
114 }
115 messages
116 }
117 };
118
119 Ok(messages)
120 }
121}