Skip to content

Commit

Permalink
Various entity improvements (#570)
Browse files Browse the repository at this point in the history
* Add new types for some fields in Channels struct (read commit desc)
- Conditionally compile applied_tags for sqlx feature
- Add DefaultForumLayout enum
- Add DefaultSearchOrder enum

* Add todo on ChannelCreateSchema

* Change DefaultSearchOrder to DefaultSortOrder

* remove unneeded import

* rename columns for sql(x)

* add note about backend feature

* rename struct fields of UserNote to be more sensible
  • Loading branch information
bitfl0wer authored Oct 13, 2024
1 parent 0938dd8 commit 4d9cac4
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 10 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ to run the tests for wasm.

## Versioning

This crate uses Semantic Versioning 2.0.0 as its versioning scheme. You can read the specification [here](https://semver.org/spec/v2.0.0.html).
Like other cargo crates, this crate uses Semantic Versioning 2.0.0 as its versioning scheme.
You can read the specification [here](https://semver.org/spec/v2.0.0.html).

Code gated behind the `backend` feature is not considered part of the public API and can change without
affecting semver compatibility. The `backend` feature is explicitly meant for use in [`symfonia`](https://github.com/polyphony-chat/symfonia)

## Contributing

Expand Down
134 changes: 129 additions & 5 deletions src/types/entities/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr};
use std::fmt::{Debug, Formatter};
use std::str::FromStr;

use crate::errors::ChorusError;
use crate::types::{
entities::{GuildMember, User},
utils::Snowflake,
Expand All @@ -31,7 +32,7 @@ use serde::de::{Error, Visitor};
#[cfg(feature = "sqlx")]
use sqlx::types::Json;

use super::{option_arc_rwlock_ptr_eq, option_vec_arc_rwlock_ptr_eq};
use super::{option_arc_rwlock_ptr_eq, option_vec_arc_rwlock_ptr_eq, Emoji};

#[derive(Default, Debug, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
Expand All @@ -42,17 +43,23 @@ use super::{option_arc_rwlock_ptr_eq, option_vec_arc_rwlock_ptr_eq};
/// See <https://discord-userdoccers.vercel.app/resources/channel#channels-resource>
pub struct Channel {
pub application_id: Option<Snowflake>,
pub applied_tags: Option<Vec<String>>,
#[cfg(not(feature = "sqlx"))]
pub applied_tags: Option<Vec<Snowflake>>,
#[cfg(feature = "sqlx")]
pub applied_tags: Option<Json<Vec<Snowflake>>>,
#[cfg(not(feature = "sqlx"))]
pub available_tags: Option<Vec<Tag>>,
#[cfg(feature = "sqlx")]
pub available_tags: Option<Json<Vec<Tag>>>,
pub bitrate: Option<i32>,
#[serde(rename = "type")]
#[cfg_attr(feature = "sqlx", sqlx(rename = "type"))]
pub channel_type: ChannelType,
pub created_at: Option<chrono::DateTime<Utc>>,
pub default_auto_archive_duration: Option<i32>,
pub default_forum_layout: Option<i32>,
// DefaultReaction could be stored in a separate table. However, there are a lot of default emojis. How would we handle that?
pub default_forum_layout: Option<DefaultForumLayout>,
pub default_reaction_emoji: Option<DefaultReaction>,
pub default_sort_order: Option<i32>,
pub default_sort_order: Option<DefaultSortOrder>,
pub default_thread_rate_limit_per_user: Option<i32>,
pub flags: Option<i32>,
pub guild_id: Option<Snowflake>,
Expand Down Expand Up @@ -325,6 +332,15 @@ pub struct DefaultReaction {
pub emoji_name: Option<String>,
}

impl From<Emoji> for DefaultReaction {
fn from(value: Emoji) -> Self {
Self {
emoji_id: Some(value.id),
emoji_name: value.name,
}
}
}

#[derive(
Default,
Clone,
Expand Down Expand Up @@ -401,3 +417,111 @@ pub struct FollowedChannel {
pub channel_id: Snowflake,
pub webhook_id: Snowflake,
}

#[derive(
Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Copy, Hash, PartialOrd, Ord, Default,
)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[repr(u8)]
pub enum DefaultForumLayout {
#[default]
Default = 0,
List = 1,
Grid = 2,
}

impl TryFrom<u8> for DefaultForumLayout {
type Error = ChorusError;

fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(DefaultForumLayout::Default),
1 => Ok(DefaultForumLayout::List),
2 => Ok(DefaultForumLayout::Grid),
_ => Err(ChorusError::InvalidArguments {
error: "Value is not a valid DefaultForumLayout".to_string(),
}),
}
}
}

#[cfg(feature = "sqlx")]
impl sqlx::Type<sqlx::Postgres> for DefaultForumLayout {
fn type_info() -> <sqlx::Postgres as sqlx::Database>::TypeInfo {
<sqlx_pg_uint::PgU8 as sqlx::Type<sqlx::Postgres>>::type_info()
}
}

#[cfg(feature = "sqlx")]
impl<'q> sqlx::Encode<'q, sqlx::Postgres> for DefaultForumLayout {
fn encode_by_ref(
&self,
buf: &mut <sqlx::Postgres as sqlx::Database>::ArgumentBuffer<'q>,
) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
let sqlx_pg_uint = sqlx_pg_uint::PgU8::from(*self as u8);
sqlx_pg_uint.encode_by_ref(buf)
}
}

#[cfg(feature = "sqlx")]
impl<'r> sqlx::Decode<'r, sqlx::Postgres> for DefaultForumLayout {
fn decode(
value: <sqlx::Postgres as sqlx::Database>::ValueRef<'r>,
) -> Result<Self, sqlx::error::BoxDynError> {
let sqlx_pg_uint = sqlx_pg_uint::PgU8::decode(value)?;
DefaultForumLayout::try_from(sqlx_pg_uint.to_uint()).map_err(|e| e.into())
}
}

#[derive(
Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Copy, Hash, PartialOrd, Ord, Default,
)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[repr(u8)]
pub enum DefaultSortOrder {
#[default]
LatestActivity = 0,
CreationTime = 1,
}

impl TryFrom<u8> for DefaultSortOrder {
type Error = ChorusError;

fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(DefaultSortOrder::LatestActivity),
1 => Ok(DefaultSortOrder::CreationTime),
_ => Err(ChorusError::InvalidArguments {
error: "Value is not a valid DefaultSearchOrder".to_string(),
}),
}
}
}

#[cfg(feature = "sqlx")]
impl sqlx::Type<sqlx::Postgres> for DefaultSortOrder {
fn type_info() -> <sqlx::Postgres as sqlx::Database>::TypeInfo {
<sqlx_pg_uint::PgU8 as sqlx::Type<sqlx::Postgres>>::type_info()
}
}

#[cfg(feature = "sqlx")]
impl<'q> sqlx::Encode<'q, sqlx::Postgres> for DefaultSortOrder {
fn encode_by_ref(
&self,
buf: &mut <sqlx::Postgres as sqlx::Database>::ArgumentBuffer<'q>,
) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
let sqlx_pg_uint = sqlx_pg_uint::PgU8::from(*self as u8);
sqlx_pg_uint.encode_by_ref(buf)
}
}

#[cfg(feature = "sqlx")]
impl<'r> sqlx::Decode<'r, sqlx::Postgres> for DefaultSortOrder {
fn decode(
value: <sqlx::Postgres as sqlx::Database>::ValueRef<'r>,
) -> Result<Self, sqlx::error::BoxDynError> {
let sqlx_pg_uint = sqlx_pg_uint::PgU8::decode(value)?;
DefaultSortOrder::try_from(sqlx_pg_uint.to_uint()).map_err(|e| e.into())
}
}
11 changes: 7 additions & 4 deletions src/types/entities/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use crate::errors::ChorusError;
use crate::types::utils::Snowflake;
use crate::{UInt32, UInt8};
use crate::UInt32;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_aux::prelude::{deserialize_default_from_null, deserialize_option_number_from_string};
Expand Down Expand Up @@ -826,11 +826,14 @@ pub struct MutualGuild {
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
pub struct UserNote {
/// Actual note contents; max 256 characters
pub note: String,
#[serde(rename = "note")]
pub content: String,
/// The ID of the user the note is on
pub note_user_id: Snowflake,
#[serde(rename = "note_user_id")]
pub target_id: Snowflake,
/// The ID of the user who created the note (always the current user)
pub user_id: Snowflake,
#[serde(rename = "user_id")]
pub author_id: Snowflake,
}

/// Structure which defines an affinity the local user has with another user.
Expand Down
1 change: 1 addition & 0 deletions src/types/schema/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};

use crate::types::{entities::PermissionOverwrite, ChannelType, DefaultReaction, Snowflake};

// TODO: Needs updating
#[derive(Debug, Deserialize, Serialize, Default, PartialEq, PartialOrd)]
#[serde(rename_all = "snake_case")]
pub struct ChannelCreateSchema {
Expand Down

0 comments on commit 4d9cac4

Please sign in to comment.