Add partial emoji and custom reaction types, refine SQLx mapping
This commit is contained in:
parent
590a6d6828
commit
bec0269e70
|
@ -3,6 +3,7 @@
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_aux::prelude::deserialize_number_from_string;
|
||||||
|
|
||||||
use crate::types::{config::types::subconfigs::register::{
|
use crate::types::{config::types::subconfigs::register::{
|
||||||
DateOfBirthConfiguration, PasswordConfiguration, RegistrationEmailConfiguration,
|
DateOfBirthConfiguration, PasswordConfiguration, RegistrationEmailConfiguration,
|
||||||
|
@ -22,6 +23,7 @@ pub struct RegisterConfiguration {
|
||||||
pub allow_multiple_accounts: bool,
|
pub allow_multiple_accounts: bool,
|
||||||
pub block_proxies: bool,
|
pub block_proxies: bool,
|
||||||
pub incrementing_discriminators: bool,
|
pub incrementing_discriminators: bool,
|
||||||
|
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||||
pub default_rights: Rights,
|
pub default_rights: Rights,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,9 @@ pub struct Channel {
|
||||||
pub managed: Option<bool>,
|
pub managed: Option<bool>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub member: Option<ThreadMember>,
|
pub member: Option<ThreadMember>,
|
||||||
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub member_count: Option<i32>,
|
pub member_count: Option<i32>,
|
||||||
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub message_count: Option<i32>,
|
pub message_count: Option<i32>,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub nsfw: Option<bool>,
|
pub nsfw: Option<bool>,
|
||||||
|
@ -75,6 +77,7 @@ pub struct Channel {
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
#[cfg_attr(feature = "client", observe_option_vec)]
|
#[cfg_attr(feature = "client", observe_option_vec)]
|
||||||
pub permission_overwrites: Option<Vec<Shared<PermissionOverwrite>>>,
|
pub permission_overwrites: Option<Vec<Shared<PermissionOverwrite>>>,
|
||||||
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub permissions: Option<String>,
|
pub permissions: Option<String>,
|
||||||
pub position: Option<i32>,
|
pub position: Option<i32>,
|
||||||
pub rate_limit_per_user: Option<i32>,
|
pub rate_limit_per_user: Option<i32>,
|
||||||
|
@ -85,6 +88,7 @@ pub struct Channel {
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub thread_metadata: Option<ThreadMetadata>,
|
pub thread_metadata: Option<ThreadMetadata>,
|
||||||
pub topic: Option<String>,
|
pub topic: Option<String>,
|
||||||
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub total_message_sent: Option<i32>,
|
pub total_message_sent: Option<i32>,
|
||||||
pub user_limit: Option<i32>,
|
pub user_limit: Option<i32>,
|
||||||
pub video_quality_mode: Option<i32>,
|
pub video_quality_mode: Option<i32>,
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::fmt::Debug;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::types::Shared;
|
use crate::types::{PartialEmoji, Shared};
|
||||||
use crate::types::entities::User;
|
use crate::types::entities::User;
|
||||||
use crate::types::Snowflake;
|
use crate::types::Snowflake;
|
||||||
|
|
||||||
|
@ -66,3 +66,18 @@ impl PartialEq for Emoji {
|
||||||
|| self.available != other.available)
|
|| self.available != other.available)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<PartialEmoji> for Emoji {
|
||||||
|
fn from(value: PartialEmoji) -> Self {
|
||||||
|
Self {
|
||||||
|
id: value.id.unwrap_or_default(), // TODO: this should be handled differently
|
||||||
|
name: Some(value.name),
|
||||||
|
roles: None,
|
||||||
|
user: None,
|
||||||
|
require_colons: Some(value.animated),
|
||||||
|
managed: None,
|
||||||
|
animated: Some(value.animated),
|
||||||
|
available: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,7 +59,7 @@ pub struct Guild {
|
||||||
pub emojis: Vec<Shared<Emoji>>,
|
pub emojis: Vec<Shared<Emoji>>,
|
||||||
pub explicit_content_filter: Option<ExplicitContentFilterLevel>,
|
pub explicit_content_filter: Option<ExplicitContentFilterLevel>,
|
||||||
//#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))]
|
//#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))]
|
||||||
pub features: Option<GuildFeaturesList>,
|
pub features: GuildFeaturesList,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub icon_hash: Option<String>,
|
pub icon_hash: Option<String>,
|
||||||
|
@ -111,7 +111,7 @@ pub struct Guild {
|
||||||
#[cfg_attr(feature = "client", observe_option_vec)]
|
#[cfg_attr(feature = "client", observe_option_vec)]
|
||||||
pub webhooks: Option<Vec<Shared<Webhook>>>,
|
pub webhooks: Option<Vec<Shared<Webhook>>>,
|
||||||
#[cfg(feature = "sqlx")]
|
#[cfg(feature = "sqlx")]
|
||||||
pub welcome_screen: Option<sqlx::types::Json<WelcomeScreenObject>>,
|
pub welcome_screen: sqlx::types::Json<Option<WelcomeScreenObject>>,
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
pub welcome_screen: Option<WelcomeScreenObject>,
|
pub welcome_screen: Option<WelcomeScreenObject>,
|
||||||
pub widget_channel_id: Option<Snowflake>,
|
pub widget_channel_id: Option<Snowflake>,
|
||||||
|
|
|
@ -16,7 +16,9 @@ use super::{Application, Channel, GuildMember, NSFWLevel, User};
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
||||||
pub struct Invite {
|
pub struct Invite {
|
||||||
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub approximate_member_count: Option<i32>,
|
pub approximate_member_count: Option<i32>,
|
||||||
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub approximate_presence_count: Option<i32>,
|
pub approximate_presence_count: Option<i32>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub channel: Option<Channel>,
|
pub channel: Option<Channel>,
|
||||||
|
@ -45,7 +47,7 @@ pub struct Invite {
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub target_user: Option<User>,
|
pub target_user: Option<User>,
|
||||||
pub temporary: Option<bool>,
|
pub temporary: Option<bool>,
|
||||||
pub uses: Option<i32>,
|
pub uses: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The guild an invite is for.
|
/// The guild an invite is for.
|
||||||
|
@ -77,16 +79,16 @@ impl From<Guild> for InviteGuild {
|
||||||
icon: value.icon,
|
icon: value.icon,
|
||||||
splash: value.splash,
|
splash: value.splash,
|
||||||
verification_level: value.verification_level.unwrap_or_default(),
|
verification_level: value.verification_level.unwrap_or_default(),
|
||||||
features: value.features.unwrap_or_default(),
|
features: value.features,
|
||||||
vanity_url_code: value.vanity_url_code,
|
vanity_url_code: value.vanity_url_code,
|
||||||
description: value.description,
|
description: value.description,
|
||||||
banner: value.banner,
|
banner: value.banner,
|
||||||
premium_subscription_count: value.premium_subscription_count,
|
premium_subscription_count: value.premium_subscription_count,
|
||||||
nsfw_deprecated: None,
|
nsfw_deprecated: None,
|
||||||
nsfw_level: value.nsfw_level.unwrap_or_default(),
|
nsfw_level: value.nsfw_level.unwrap_or_default(),
|
||||||
welcome_screen: value.welcome_screen.map(|obj| {
|
welcome_screen: value.welcome_screen.0.map(|obj| {
|
||||||
#[cfg(feature = "sqlx")]
|
#[cfg(feature = "sqlx")]
|
||||||
let res = obj.0;
|
let res = obj;
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
let res = obj;
|
let res = obj;
|
||||||
res
|
res
|
||||||
|
|
|
@ -75,13 +75,14 @@ pub struct Message {
|
||||||
pub interaction: Option<MessageInteraction>,
|
pub interaction: Option<MessageInteraction>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub thread: Option<Channel>,
|
pub thread: Option<Channel>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub components: Option<sqlx::types::Json<Vec<Component>>>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
pub components: Option<Vec<Component>>,
|
pub components: Option<Vec<Component>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub sticker_items: Option<Vec<StickerItem>>,
|
pub sticker_items: Option<Vec<StickerItem>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub stickers: Option<Vec<Sticker>>,
|
pub stickers: Option<Vec<Sticker>>,
|
||||||
pub position: Option<i32>,
|
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub role_subscription_data: Option<RoleSubscriptionData>,
|
pub role_subscription_data: Option<RoleSubscriptionData>,
|
||||||
}
|
}
|
||||||
|
@ -116,7 +117,7 @@ impl PartialEq for Message {
|
||||||
&& self.thread == other.thread
|
&& self.thread == other.thread
|
||||||
&& self.components == other.components
|
&& self.components == other.components
|
||||||
&& self.sticker_items == other.sticker_items
|
&& self.sticker_items == other.sticker_items
|
||||||
&& self.position == other.position
|
// && self.position == other.position
|
||||||
&& self.role_subscription_data == other.role_subscription_data
|
&& self.role_subscription_data == other.role_subscription_data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,12 +126,22 @@ impl PartialEq for Message {
|
||||||
/// # Reference
|
/// # Reference
|
||||||
/// See <https://discord-userdoccers.vercel.app/resources/message#message-reference-object>
|
/// See <https://discord-userdoccers.vercel.app/resources/message#message-reference-object>
|
||||||
pub struct MessageReference {
|
pub struct MessageReference {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub reference_type: MessageReferenceType,
|
||||||
pub message_id: Snowflake,
|
pub message_id: Snowflake,
|
||||||
pub channel_id: Snowflake,
|
pub channel_id: Snowflake,
|
||||||
pub guild_id: Option<Snowflake>,
|
pub guild_id: Option<Snowflake>,
|
||||||
pub fail_if_not_exists: Option<bool>,
|
pub fail_if_not_exists: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Eq, Ord, PartialOrd)]
|
||||||
|
pub enum MessageReferenceType {
|
||||||
|
/// A standard reference used by replies and system messages
|
||||||
|
Default = 0,
|
||||||
|
/// A reference used to point to a message at a point in time
|
||||||
|
Forward = 1,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct MessageInteraction {
|
pub struct MessageInteraction {
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
|
@ -404,4 +415,22 @@ bitflags! {
|
||||||
/// This message has a forwarded message snapshot attached
|
/// This message has a forwarded message snapshot attached
|
||||||
const HAS_SNAPSHOT = 1 << 14;
|
const HAS_SNAPSHOT = 1 << 14;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct PartialEmoji {
|
||||||
|
#[serde(default)]
|
||||||
|
pub id: Option<Snowflake>,
|
||||||
|
pub name: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub animated: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, PartialOrd)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum ReactionType {
|
||||||
|
Normal = 0,
|
||||||
|
Burst = 1, // The dreaded super reactions
|
||||||
}
|
}
|
|
@ -59,7 +59,7 @@ pub struct GetChannelMessagesSchema {
|
||||||
/// Between 1 and 100, defaults to 50.
|
/// Between 1 and 100, defaults to 50.
|
||||||
pub limit: Option<i32>,
|
pub limit: Option<i32>,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub anchor: ChannelMessagesAnchor,
|
pub anchor: Option<ChannelMessagesAnchor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
|
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
|
||||||
|
@ -74,21 +74,21 @@ impl GetChannelMessagesSchema {
|
||||||
pub fn before(anchor: Snowflake) -> Self {
|
pub fn before(anchor: Snowflake) -> Self {
|
||||||
Self {
|
Self {
|
||||||
limit: None,
|
limit: None,
|
||||||
anchor: ChannelMessagesAnchor::Before(anchor),
|
anchor: Some(ChannelMessagesAnchor::Before(anchor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn around(anchor: Snowflake) -> Self {
|
pub fn around(anchor: Snowflake) -> Self {
|
||||||
Self {
|
Self {
|
||||||
limit: None,
|
limit: None,
|
||||||
anchor: ChannelMessagesAnchor::Around(anchor),
|
anchor: Some(ChannelMessagesAnchor::Around(anchor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn after(anchor: Snowflake) -> Self {
|
pub fn after(anchor: Snowflake) -> Self {
|
||||||
Self {
|
Self {
|
||||||
limit: None,
|
limit: None,
|
||||||
anchor: ChannelMessagesAnchor::After(anchor),
|
anchor: Some(ChannelMessagesAnchor::After(anchor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use crate::types::entities::{
|
use crate::types::entities::{
|
||||||
AllowedMention, Component, Embed, MessageReference, PartialDiscordFileAttachment,
|
AllowedMention, Component, Embed, MessageReference, PartialDiscordFileAttachment,
|
||||||
};
|
};
|
||||||
use crate::types::{Attachment, MessageFlags, MessageType, Snowflake};
|
use crate::types::{Attachment, MessageFlags, MessageType, ReactionType, Snowflake};
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
|
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
|
@ -118,13 +118,21 @@ pub struct MessageAck {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
|
||||||
pub struct MessageModifySchema {
|
pub struct MessageModifySchema {
|
||||||
content: Option<String>,
|
pub content: Option<String>,
|
||||||
embeds: Option<Vec<Embed>>,
|
pub embeds: Option<Vec<Embed>>,
|
||||||
embed: Option<Embed>,
|
pub embed: Option<Embed>,
|
||||||
allowed_mentions: Option<AllowedMention>,
|
pub allowed_mentions: Option<AllowedMention>,
|
||||||
components: Option<Vec<Component>>,
|
pub components: Option<Vec<Component>>,
|
||||||
flags: Option<MessageFlags>,
|
pub flags: Option<MessageFlags>,
|
||||||
files: Option<Vec<u8>>,
|
pub files: Option<Vec<u8>>,
|
||||||
payload_json: Option<String>,
|
pub payload_json: Option<String>,
|
||||||
attachments: Option<Vec<Attachment>>,
|
pub attachments: Option<Vec<Attachment>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
|
||||||
|
pub struct ReactionQuerySchema {
|
||||||
|
pub after: Option<Snowflake>,
|
||||||
|
pub limit: Option<u32>,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub reaction_type: Option<ReactionType>
|
||||||
|
}
|
|
@ -2,11 +2,11 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
use std::num::ParseIntError;
|
||||||
|
use std::str::FromStr;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use crate::types::UserFlags;
|
||||||
#[cfg(feature = "sqlx")]
|
|
||||||
use sqlx::{{Decode, Encode, MySql}, database::{HasArguments, HasValueRef}, encode::IsNull, error::BoxDynError, mysql::MySqlValueRef};
|
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Rights are instance-wide, per-user permissions for everything you may perform on the instance,
|
/// Rights are instance-wide, per-user permissions for everything you may perform on the instance,
|
||||||
|
@ -18,7 +18,7 @@ bitflags! {
|
||||||
///
|
///
|
||||||
/// # Reference
|
/// # Reference
|
||||||
/// See <https://docs.spacebar.chat/setup/server/security/rights/>
|
/// See <https://docs.spacebar.chat/setup/server/security/rights/>
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, chorus_macros::SqlxBitFlags)]
|
||||||
pub struct Rights: u64 {
|
pub struct Rights: u64 {
|
||||||
/// All rights
|
/// All rights
|
||||||
const OPERATOR = 1 << 0;
|
const OPERATOR = 1 << 0;
|
||||||
|
@ -132,33 +132,28 @@ bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sqlx")]
|
impl FromStr for Rights {
|
||||||
impl sqlx::Type<MySql> for Rights {
|
type Err = ParseIntError;
|
||||||
fn type_info() -> <sqlx::MySql as sqlx::Database>::TypeInfo {
|
|
||||||
u64::type_info()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compatible(ty: &<sqlx::MySql as sqlx::Database>::TypeInfo) -> bool {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
u64::compatible(ty)
|
s.parse::<u64>().map(Rights::from_bits).map(|f| f.unwrap_or(Rights::empty()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sqlx")]
|
impl Serialize for Rights {
|
||||||
impl<'q> Encode<'q, MySql> for Rights {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
fn encode_by_ref(&self, buf: &mut <MySql as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
serializer.serialize_str(&self.bits().to_string())
|
||||||
<u64 as Encode<MySql>>::encode_by_ref(&self.0.0, buf)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sqlx")]
|
impl<'de> Deserialize<'de> for Rights {
|
||||||
impl<'r> Decode<'r, MySql> for Rights {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
||||||
fn decode(value: <MySql as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
let s = String::deserialize(deserializer)?.parse::<u64>().map_err(serde::de::Error::custom)?;
|
||||||
let raw = <u64 as Decode<MySql>>::decode(value)?;
|
|
||||||
Ok(Rights::from_bits(raw).unwrap())
|
Ok(Rights::from_bits(s).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Rights {
|
impl Rights {
|
||||||
pub fn any(&self, permission: Rights, check_operator: bool) -> bool {
|
pub fn any(&self, permission: Rights, check_operator: bool) -> bool {
|
||||||
(check_operator && self.contains(Rights::OPERATOR)) || self.contains(permission)
|
(check_operator && self.contains(Rights::OPERATOR)) || self.contains(permission)
|
||||||
|
|
|
@ -8,6 +8,9 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono::{DateTime, TimeZone, Utc};
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
use sqlx::{MySql, TypeInfo};
|
||||||
|
use sqlx::database::HasArguments;
|
||||||
|
use sqlx::encode::IsNull;
|
||||||
#[cfg(feature = "sqlx")]
|
#[cfg(feature = "sqlx")]
|
||||||
use sqlx::Type;
|
use sqlx::Type;
|
||||||
|
|
||||||
|
@ -19,8 +22,6 @@ const EPOCH: i64 = 1420070400000;
|
||||||
/// # Reference
|
/// # Reference
|
||||||
/// See <https://discord.com/developers/docs/reference#snowflakes>
|
/// See <https://discord.com/developers/docs/reference#snowflakes>
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
#[cfg_attr(feature = "sqlx", derive(Type))]
|
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(transparent))]
|
|
||||||
pub struct Snowflake(pub u64);
|
pub struct Snowflake(pub u64);
|
||||||
|
|
||||||
impl Snowflake {
|
impl Snowflake {
|
||||||
|
@ -102,6 +103,24 @@ impl<'de> serde::Deserialize<'de> for Snowflake {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl sqlx::Type<sqlx::MySql> for Snowflake {
|
||||||
|
fn type_info() -> <sqlx::MySql as sqlx::Database>::TypeInfo {
|
||||||
|
<String as sqlx::Type<sqlx::MySql>>::type_info()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'q> sqlx::Encode<'q, sqlx::MySql> for Snowflake {
|
||||||
|
fn encode_by_ref(&self, buf: &mut <sqlx::MySql as sqlx::database::HasArguments<'q>>::ArgumentBuffer) -> sqlx::encode::IsNull {
|
||||||
|
<String as sqlx::Encode<'q, sqlx::MySql>>::encode_by_ref(&self.0.to_string(), buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> sqlx::Decode<'d, sqlx::MySql> for Snowflake {
|
||||||
|
fn decode(value: <sqlx::MySql as sqlx::database::HasValueRef<'d>>::ValueRef) -> Result<Self, sqlx::error::BoxDynError> {
|
||||||
|
<String as sqlx::Decode<'d, sqlx::MySql>>::decode(value).map(|s| s.parse::<u64>().map(Snowflake).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
|
Loading…
Reference in New Issue