serenity/utils/argument_convert/
message.rs1use std::fmt;
2
3use super::ArgumentConvert;
4use crate::model::prelude::*;
5use crate::prelude::*;
6
7#[non_exhaustive]
9#[derive(Debug)]
10pub enum MessageParseError {
11 Malformed,
13 Http(SerenityError),
15 HttpNotAvailable,
17}
18
19impl std::error::Error for MessageParseError {
20 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
21 match self {
22 Self::Http(e) => Some(e),
23 Self::HttpNotAvailable | Self::Malformed => None,
24 }
25 }
26}
27
28impl fmt::Display for MessageParseError {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 Self::Malformed => {
32 f.write_str("Provided string did not adhere to any known guild message format")
33 },
34 Self::Http(_) => f.write_str("Failed to request message data via HTTP"),
35 Self::HttpNotAvailable => f.write_str(
36 "Gateway feature is disabled and the required information was not in cache",
37 ),
38 }
39 }
40}
41
42#[async_trait::async_trait]
50impl ArgumentConvert for Message {
51 type Err = MessageParseError;
52
53 async fn convert(
54 ctx: impl CacheHttp,
55 _guild_id: Option<GuildId>,
56 channel_id: Option<ChannelId>,
57 s: &str,
58 ) -> Result<Self, Self::Err> {
59 let extract_from_message_id = || Some((channel_id?, s.parse().ok()?));
60
61 let extract_from_message_url = || {
62 let (_guild_id, channel_id, message_id) = crate::utils::parse_message_url(s)?;
63 Some((channel_id, message_id))
64 };
65
66 let (channel_id, message_id) = crate::utils::parse_message_id_pair(s)
67 .or_else(extract_from_message_id)
68 .or_else(extract_from_message_url)
69 .ok_or(MessageParseError::Malformed)?;
70
71 channel_id.message(ctx, message_id).await.map_err(MessageParseError::Http)
72 }
73}