revolt_database/util/
reference.rs1use std::str::FromStr;
2
3use revolt_result::Result;
4#[cfg(feature = "rocket-impl")]
5use rocket::request::FromParam;
6#[cfg(feature = "rocket-impl")]
7use schemars::{
8 schema::{InstanceType, Schema, SchemaObject, SingleOrVec},
9 JsonSchema,
10};
11
12use crate::{
13 Bot, Channel, Database, Emoji, Invite, Member, Message, Server, ServerBan, User, Webhook,
14};
15
16pub struct Reference<'a> {
18 pub id: &'a str,
20}
21
22impl<'a> Reference<'a> {
23 pub fn from_unchecked(id: &'a str) -> Reference<'a> {
25 Reference { id }
26 }
27
28 pub async fn as_ban(&self, db: &Database, server: &str) -> Result<ServerBan> {
30 db.fetch_ban(server, self.id).await
31 }
32
33 pub async fn as_bot(&self, db: &Database) -> Result<Bot> {
35 db.fetch_bot(self.id).await
36 }
37
38 pub async fn as_emoji(&self, db: &Database) -> Result<Emoji> {
40 db.fetch_emoji(self.id).await
41 }
42
43 pub async fn as_channel(&self, db: &Database) -> Result<Channel> {
45 db.fetch_channel(self.id).await
46 }
47
48 pub async fn as_invite(&self, db: &Database) -> Result<Invite> {
50 if ulid::Ulid::from_str(self.id).is_ok() {
51 let server = self.as_server(db).await?;
52 if !server.discoverable {
53 return Err(create_error!(NotFound));
54 }
55
56 Ok(Invite::Server {
57 code: self.id.to_string(),
58 server: server.id,
59 creator: server.owner,
60 channel: server
61 .channels
62 .into_iter()
63 .next()
64 .ok_or(create_error!(NotFound))?,
65 })
66 } else {
67 db.fetch_invite(self.id).await
68 }
69 }
70
71 pub async fn as_message(&self, db: &Database) -> Result<Message> {
73 db.fetch_message(self.id).await
74 }
75
76 pub async fn as_message_in_channel(&self, db: &Database, channel: &str) -> Result<Message> {
78 let msg = db.fetch_message(self.id).await?;
79 if msg.channel != channel {
80 return Err(create_error!(NotFound));
81 }
82
83 Ok(msg)
84 }
85
86 pub async fn as_member(&self, db: &Database, server: &str) -> Result<Member> {
88 db.fetch_member(server, self.id).await
89 }
90
91 pub async fn as_server(&self, db: &Database) -> Result<Server> {
93 db.fetch_server(self.id).await
94 }
95
96 pub async fn as_user(&self, db: &Database) -> Result<User> {
98 db.fetch_user(self.id).await
99 }
100
101 pub async fn as_webhook(&self, db: &Database) -> Result<Webhook> {
103 db.fetch_webhook(self.id).await
104 }
105}
106
107#[cfg(feature = "rocket-impl")]
108impl<'r> FromParam<'r> for Reference<'r> {
109 type Error = &'r str;
110
111 fn from_param(param: &'r str) -> Result<Self, Self::Error> {
112 Ok(Reference::from_unchecked(param))
113 }
114}
115
116#[cfg(feature = "rocket-impl")]
117impl<'a> JsonSchema for Reference<'a> {
118 fn schema_name() -> String {
119 "Id".to_string()
120 }
121
122 fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> Schema {
123 Schema::Object(SchemaObject {
124 instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
125 ..Default::default()
126 })
127 }
128}