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