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
16#[derive(Serialize, Deserialize)]
18pub struct Reference {
19 pub id: String,
21}
22
23impl Reference {
24 pub fn from_unchecked(id: String) -> Reference {
26 Reference { id }
27 }
28
29 pub async fn as_ban(&self, db: &Database, server: &str) -> Result<ServerBan> {
31 db.fetch_ban(server, &self.id).await
32 }
33
34 pub async fn as_bot(&self, db: &Database) -> Result<Bot> {
36 db.fetch_bot(&self.id).await
37 }
38
39 pub async fn as_emoji(&self, db: &Database) -> Result<Emoji> {
41 db.fetch_emoji(&self.id).await
42 }
43
44 pub async fn as_channel(&self, db: &Database) -> Result<Channel> {
46 db.fetch_channel(&self.id).await
47 }
48
49 pub async fn as_invite(&self, db: &Database) -> Result<Invite> {
51 if ulid::Ulid::from_str(&self.id).is_ok() {
52 let server = self.as_server(db).await?;
53 if !server.discoverable {
54 return Err(create_error!(NotFound));
55 }
56
57 Ok(Invite::Server {
58 code: self.id.to_string(),
59 server: server.id,
60 creator: server.owner,
61 channel: server
62 .channels
63 .into_iter()
64 .next()
65 .ok_or(create_error!(NotFound))?,
66 })
67 } else {
68 db.fetch_invite(&self.id).await
69 }
70 }
71
72 pub async fn as_message(&self, db: &Database) -> Result<Message> {
74 db.fetch_message(&self.id).await
75 }
76
77 pub async fn as_message_in_channel(&self, db: &Database, channel: &str) -> Result<Message> {
79 let msg = db.fetch_message(&self.id).await?;
80 if msg.channel != channel {
81 return Err(create_error!(NotFound));
82 }
83
84 Ok(msg)
85 }
86
87 pub async fn as_member(&self, db: &Database, server: &str) -> Result<Member> {
89 db.fetch_member(server, &self.id).await
90 }
91
92 pub async fn as_server(&self, db: &Database) -> Result<Server> {
94 db.fetch_server(&self.id).await
95 }
96
97 pub async fn as_user(&self, db: &Database) -> Result<User> {
99 db.fetch_user(&self.id).await
100 }
101
102 pub async fn as_webhook(&self, db: &Database) -> Result<Webhook> {
104 db.fetch_webhook(&self.id).await
105 }
106}
107
108#[cfg(feature = "rocket-impl")]
109impl<'r> FromParam<'r> for Reference {
110 type Error = &'r str;
111
112 fn from_param(param: &'r str) -> Result<Self, Self::Error> {
113 Ok(Reference::from_unchecked(param.into()))
114 }
115}
116
117#[cfg(feature = "rocket-impl")]
118impl JsonSchema for Reference {
119 fn schema_name() -> String {
120 "Id".to_string()
121 }
122
123 fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> Schema {
124 Schema::Object(SchemaObject {
125 instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
126 ..Default::default()
127 })
128 }
129}