forked from jmug/stoatchat
refactor(core/models): swap dependency order with db
feat(core/models): implement webhook model
This commit is contained in:
@@ -11,19 +11,18 @@ description = "Revolt Backend: API Models"
|
|||||||
[features]
|
[features]
|
||||||
serde = [ "dep:serde" ]
|
serde = [ "dep:serde" ]
|
||||||
schemas = [ "dep:schemars" ]
|
schemas = [ "dep:schemars" ]
|
||||||
from_database = [ "revolt-database", "revolt-presence" ]
|
validator = [ "dep:validator" ]
|
||||||
|
partials = [ "dep:revolt_optional_struct", "serde", "schemas" ]
|
||||||
|
|
||||||
redis-is-patched = [ "revolt-presence/redis-is-patched" ]
|
default = [ "serde", "partials" ]
|
||||||
|
|
||||||
default = [ "serde", "from_database" ]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Repo
|
|
||||||
revolt-database = { version = "0.0.2", path = "../database", optional = true }
|
|
||||||
revolt-presence = { version = "0.0.2", path = "../presence", optional = true }
|
|
||||||
|
|
||||||
# Serialisation
|
# Serialisation
|
||||||
|
revolt_optional_struct = { version = "0.2.0", optional = true }
|
||||||
serde = { version = "1", features = ["derive"], optional = true }
|
serde = { version = "1", features = ["derive"], optional = true }
|
||||||
|
|
||||||
# Spec Generation
|
# Spec Generation
|
||||||
schemars = { version = "0.8.8", optional = true }
|
schemars = { version = "0.8.8", optional = true }
|
||||||
|
|
||||||
|
# Validation
|
||||||
|
validator = { version = "0.16.0", optional = true, features = ["derive"] }
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ extern crate serde;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate schemars;
|
extern crate schemars;
|
||||||
|
|
||||||
|
#[cfg(feature = "partials")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate revolt_optional_struct;
|
||||||
|
|
||||||
|
#[cfg(feature = "validator")]
|
||||||
|
pub use validator;
|
||||||
|
|
||||||
macro_rules! auto_derived {
|
macro_rules! auto_derived {
|
||||||
( $( $item:item )+ ) => {
|
( $( $item:item )+ ) => {
|
||||||
$(
|
$(
|
||||||
@@ -17,6 +24,28 @@ macro_rules! auto_derived {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "partials")]
|
||||||
|
macro_rules! auto_derived_partial {
|
||||||
|
( $item:item, $name:expr ) => {
|
||||||
|
#[derive(
|
||||||
|
OptionalStruct, Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
|
#[optional_derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||||
|
#[optional_name = $name]
|
||||||
|
#[opt_skip_serializing_none]
|
||||||
|
#[opt_some_priority]
|
||||||
|
$item
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "partials"))]
|
||||||
|
macro_rules! auto_derived_partial {
|
||||||
|
( $item:item, $name:expr ) => {
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||||
|
$item
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub mod v0;
|
pub mod v0;
|
||||||
|
|
||||||
/// Utility function to check if a boolean value is false
|
/// Utility function to check if a boolean value is false
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ auto_derived!(
|
|||||||
/// Account Strike
|
/// Account Strike
|
||||||
pub struct AccountStrike {
|
pub struct AccountStrike {
|
||||||
/// Strike Id
|
/// Strike Id
|
||||||
#[serde(rename = "_id")]
|
#[cfg_attr(feature = "serde", serde(rename = "_id"))]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
/// Id of reported user
|
/// Id of reported user
|
||||||
pub user_id: String,
|
pub user_id: String,
|
||||||
@@ -26,14 +26,3 @@ auto_derived!(
|
|||||||
pub reason: String,
|
pub reason: String,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::AccountStrike> for AccountStrike {
|
|
||||||
fn from(value: revolt_database::AccountStrike) -> Self {
|
|
||||||
AccountStrike {
|
|
||||||
id: value.id,
|
|
||||||
user_id: value.user_id,
|
|
||||||
reason: value.reason,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ auto_derived!(
|
|||||||
/// Bot
|
/// Bot
|
||||||
pub struct Bot {
|
pub struct Bot {
|
||||||
/// Bot Id
|
/// Bot Id
|
||||||
#[serde(rename = "_id")]
|
#[cfg_attr(feature = "serde", serde(rename = "_id"))]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
|
||||||
/// User Id of the bot owner
|
/// User Id of the bot owner
|
||||||
#[serde(rename = "owner")]
|
#[cfg_attr(feature = "serde", serde(rename = "owner"))]
|
||||||
pub owner_id: String,
|
pub owner_id: String,
|
||||||
/// Token used to authenticate requests for this bot
|
/// Token used to authenticate requests for this bot
|
||||||
pub token: String,
|
pub token: String,
|
||||||
@@ -66,16 +66,16 @@ auto_derived!(
|
|||||||
pub struct PublicBot {
|
pub struct PublicBot {
|
||||||
/// Bot Id
|
/// Bot Id
|
||||||
#[serde(rename = "_id")]
|
#[serde(rename = "_id")]
|
||||||
id: String,
|
pub id: String,
|
||||||
|
|
||||||
/// Bot Username
|
/// Bot Username
|
||||||
username: String,
|
pub username: String,
|
||||||
/// Profile Avatar
|
/// Profile Avatar
|
||||||
#[serde(skip_serializing_if = "String::is_empty")]
|
#[serde(skip_serializing_if = "String::is_empty")]
|
||||||
avatar: String,
|
pub avatar: String,
|
||||||
/// Profile Description
|
/// Profile Description
|
||||||
#[serde(skip_serializing_if = "String::is_empty")]
|
#[serde(skip_serializing_if = "String::is_empty")]
|
||||||
description: String,
|
pub description: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bot Response
|
/// Bot Response
|
||||||
@@ -86,39 +86,3 @@ auto_derived!(
|
|||||||
pub user: User,
|
pub user: User,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl PublicBot {
|
|
||||||
pub fn from(bot: revolt_database::Bot, user: revolt_database::User) -> Self {
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
assert_eq!(bot.id, user.id);
|
|
||||||
|
|
||||||
PublicBot {
|
|
||||||
id: bot.id,
|
|
||||||
username: user.username,
|
|
||||||
avatar: user.avatar.map(|x| x.id).unwrap_or_default(),
|
|
||||||
description: user
|
|
||||||
.profile
|
|
||||||
.map(|profile| profile.content)
|
|
||||||
.unwrap_or_default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::Bot> for Bot {
|
|
||||||
fn from(value: revolt_database::Bot) -> Self {
|
|
||||||
Bot {
|
|
||||||
id: value.id,
|
|
||||||
owner_id: value.owner,
|
|
||||||
token: value.token,
|
|
||||||
public: value.public,
|
|
||||||
analytics: value.analytics,
|
|
||||||
discoverable: value.discoverable,
|
|
||||||
interactions_url: value.interactions_url,
|
|
||||||
terms_of_service_url: value.terms_of_service_url,
|
|
||||||
privacy_policy_url: value.privacy_policy_url,
|
|
||||||
flags: value.flags.unwrap_or_default() as u32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
90
crates/core/models/src/v0/channel_webhooks.rs
Normal file
90
crates/core/models/src/v0/channel_webhooks.rs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
use super::File;
|
||||||
|
|
||||||
|
auto_derived_partial!(
|
||||||
|
/// Webhook
|
||||||
|
pub struct Webhook {
|
||||||
|
/// Webhook Id
|
||||||
|
pub id: String,
|
||||||
|
|
||||||
|
/// The name of the webhook
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
|
/// The avatar of the webhook
|
||||||
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
||||||
|
pub avatar: Option<File>,
|
||||||
|
|
||||||
|
/// The channel this webhook belongs to
|
||||||
|
pub channel_id: String,
|
||||||
|
|
||||||
|
/// The private token for the webhook
|
||||||
|
pub token: Option<String>,
|
||||||
|
},
|
||||||
|
"PartialWebhook"
|
||||||
|
);
|
||||||
|
|
||||||
|
auto_derived!(
|
||||||
|
/// Information about the webhook bundled with Message
|
||||||
|
pub struct MessageWebhook {
|
||||||
|
// The name of the webhook - 1 to 32 chars
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
|
// The id of the avatar of the webhook, if it has one
|
||||||
|
pub avatar: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// New webhook information
|
||||||
|
#[cfg_attr(feature = "validator", derive(validator::Validate))]
|
||||||
|
pub struct DataEditWebhook {
|
||||||
|
/// Webhook name
|
||||||
|
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 32)))]
|
||||||
|
pub name: Option<String>,
|
||||||
|
|
||||||
|
/// Avatar ID
|
||||||
|
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))]
|
||||||
|
pub avatar: Option<String>,
|
||||||
|
|
||||||
|
/// Fields to remove from webhook
|
||||||
|
#[cfg_attr(feature = "serde", serde(default))]
|
||||||
|
pub remove: Vec<FieldsWebhook>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Webhook information
|
||||||
|
pub struct ResponseWebhook {
|
||||||
|
/// Webhook Id
|
||||||
|
pub id: String,
|
||||||
|
|
||||||
|
/// Webhook name
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
|
/// Avatar ID
|
||||||
|
pub avatar: Option<String>,
|
||||||
|
|
||||||
|
/// The channel this webhook belongs to
|
||||||
|
pub channel_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Optional fields on webhook object
|
||||||
|
pub enum FieldsWebhook {
|
||||||
|
Avatar,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
impl From<Webhook> for MessageWebhook {
|
||||||
|
fn from(value: Webhook) -> Self {
|
||||||
|
MessageWebhook {
|
||||||
|
name: value.name,
|
||||||
|
avatar: value.avatar.map(|file| file.id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Webhook> for ResponseWebhook {
|
||||||
|
fn from(value: Webhook) -> Self {
|
||||||
|
ResponseWebhook {
|
||||||
|
id: value.id,
|
||||||
|
name: value.name,
|
||||||
|
avatar: value.avatar.map(|file| file.id),
|
||||||
|
channel_id: value.channel_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -54,42 +54,3 @@ auto_derived!(
|
|||||||
Audio,
|
Audio,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::File> for File {
|
|
||||||
fn from(value: revolt_database::File) -> Self {
|
|
||||||
File {
|
|
||||||
id: value.id,
|
|
||||||
tag: value.tag,
|
|
||||||
filename: value.filename,
|
|
||||||
metadata: value.metadata.into(),
|
|
||||||
content_type: value.content_type,
|
|
||||||
size: value.size,
|
|
||||||
deleted: value.deleted,
|
|
||||||
reported: value.reported,
|
|
||||||
message_id: value.message_id,
|
|
||||||
user_id: value.user_id,
|
|
||||||
server_id: value.server_id,
|
|
||||||
object_id: value.object_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::Metadata> for Metadata {
|
|
||||||
fn from(value: revolt_database::Metadata) -> Self {
|
|
||||||
match value {
|
|
||||||
revolt_database::Metadata::File => Metadata::File,
|
|
||||||
revolt_database::Metadata::Text => Metadata::Text,
|
|
||||||
revolt_database::Metadata::Image { width, height } => Metadata::Image {
|
|
||||||
width: width as usize,
|
|
||||||
height: height as usize,
|
|
||||||
},
|
|
||||||
revolt_database::Metadata::Video { width, height } => Metadata::Video {
|
|
||||||
width: width as usize,
|
|
||||||
height: height as usize,
|
|
||||||
},
|
|
||||||
revolt_database::Metadata::Audio => Metadata::Audio,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
mod account_strikes;
|
mod account_strikes;
|
||||||
mod bots;
|
mod bots;
|
||||||
|
mod channel_webhooks;
|
||||||
mod files;
|
mod files;
|
||||||
mod users;
|
mod users;
|
||||||
|
|
||||||
pub use account_strikes::*;
|
pub use account_strikes::*;
|
||||||
pub use bots::*;
|
pub use bots::*;
|
||||||
|
pub use channel_webhooks::*;
|
||||||
pub use files::*;
|
pub use files::*;
|
||||||
pub use users::*;
|
pub use users::*;
|
||||||
|
|||||||
@@ -158,109 +158,3 @@ impl CheckRelationship for Vec<Relationship> {
|
|||||||
RelationshipStatus::None
|
RelationshipStatus::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl User {
|
|
||||||
pub async fn from<P>(user: revolt_database::User, perspective: P) -> Self
|
|
||||||
where
|
|
||||||
P: Into<Option<revolt_database::User>>,
|
|
||||||
{
|
|
||||||
let relationship = if let Some(perspective) = perspective.into() {
|
|
||||||
perspective
|
|
||||||
.relations
|
|
||||||
.unwrap_or_default()
|
|
||||||
.into_iter()
|
|
||||||
.find(|relationship| relationship.id == user.id)
|
|
||||||
.map(|relationship| relationship.status.into())
|
|
||||||
.unwrap_or_default()
|
|
||||||
} else {
|
|
||||||
RelationshipStatus::None
|
|
||||||
};
|
|
||||||
|
|
||||||
// do permission stuff here
|
|
||||||
// TODO: implement permissions =)
|
|
||||||
let can_see_profile = false;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
username: user.username,
|
|
||||||
avatar: user.avatar.map(|file| file.into()),
|
|
||||||
relations: vec![],
|
|
||||||
badges: user.badges.unwrap_or_default() as u32,
|
|
||||||
status: None,
|
|
||||||
profile: None,
|
|
||||||
flags: user.flags.unwrap_or_default() as u32,
|
|
||||||
privileged: user.privileged,
|
|
||||||
bot: user.bot.map(|bot| bot.into()),
|
|
||||||
relationship,
|
|
||||||
online: can_see_profile && revolt_presence::is_online(&user.id).await,
|
|
||||||
id: user.id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::RelationshipStatus> for RelationshipStatus {
|
|
||||||
fn from(value: revolt_database::RelationshipStatus) -> Self {
|
|
||||||
match value {
|
|
||||||
revolt_database::RelationshipStatus::None => RelationshipStatus::None,
|
|
||||||
revolt_database::RelationshipStatus::User => RelationshipStatus::User,
|
|
||||||
revolt_database::RelationshipStatus::Friend => RelationshipStatus::Friend,
|
|
||||||
revolt_database::RelationshipStatus::Outgoing => RelationshipStatus::Outgoing,
|
|
||||||
revolt_database::RelationshipStatus::Incoming => RelationshipStatus::Incoming,
|
|
||||||
revolt_database::RelationshipStatus::Blocked => RelationshipStatus::Blocked,
|
|
||||||
revolt_database::RelationshipStatus::BlockedOther => RelationshipStatus::BlockedOther,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::Relationship> for Relationship {
|
|
||||||
fn from(value: revolt_database::Relationship) -> Self {
|
|
||||||
Self {
|
|
||||||
user_id: value.id,
|
|
||||||
status: value.status.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::Presence> for Presence {
|
|
||||||
fn from(value: revolt_database::Presence) -> Self {
|
|
||||||
match value {
|
|
||||||
revolt_database::Presence::Online => Presence::Online,
|
|
||||||
revolt_database::Presence::Idle => Presence::Idle,
|
|
||||||
revolt_database::Presence::Focus => Presence::Focus,
|
|
||||||
revolt_database::Presence::Busy => Presence::Busy,
|
|
||||||
revolt_database::Presence::Invisible => Presence::Invisible,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::UserStatus> for UserStatus {
|
|
||||||
fn from(value: revolt_database::UserStatus) -> Self {
|
|
||||||
UserStatus {
|
|
||||||
text: value.text,
|
|
||||||
presence: value.presence.map(|presence| presence.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::UserProfile> for UserProfile {
|
|
||||||
fn from(value: revolt_database::UserProfile) -> Self {
|
|
||||||
UserProfile {
|
|
||||||
content: value.content,
|
|
||||||
background: value.background.map(|file| file.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "from_database")]
|
|
||||||
impl From<revolt_database::BotInformation> for BotInformation {
|
|
||||||
fn from(value: revolt_database::BotInformation) -> Self {
|
|
||||||
BotInformation {
|
|
||||||
owner_id: value.owner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user