Skip to main content

mutiny_rs/builders/
fetch_messages.rs

1use 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}