Skip to content

Commit

Permalink
Make Relationship struct sqlx/symfonia-ready
Browse files Browse the repository at this point in the history
  • Loading branch information
bitfl0wer committed Oct 8, 2024
1 parent b87df59 commit 8081352
Showing 1 changed file with 58 additions and 2 deletions.
60 changes: 58 additions & 2 deletions src/types/entities/relationship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,28 @@ use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};

use crate::errors::ChorusError;
use crate::types::{Shared, Snowflake};

use super::{arc_rwlock_ptr_eq, PublicUser};

#[derive(Debug, Deserialize, Serialize, Clone, Default)]
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
/// See <https://discord-userdoccers.vercel.app/resources/user#relationship-structure>
pub struct Relationship {
/// The ID of the target user
#[cfg_attr(feature = "sqlx", sqlx(rename = "to_id"))]
pub id: Snowflake,
#[serde(rename = "type")]
#[cfg_attr(feature = "sqlx", sqlx(rename = "type"))]
pub relationship_type: RelationshipType,
#[cfg_attr(feature = "sqlx", sqlx(skip))] // Can be derived from the user id
/// The nickname of the user in this relationship
pub nickname: Option<String>,
#[cfg_attr(feature = "sqlx", sqlx(skip))] // Can be derived from the user id
/// The target user
pub user: Shared<PublicUser>,
/// When the user requested a relationship
pub since: Option<DateTime<Utc>>,
}

Expand Down Expand Up @@ -45,8 +55,7 @@ impl PartialEq for Relationship {
Copy,
Hash,
)]
#[cfg_attr(not(feature = "sqlx"), repr(u8))]
#[cfg_attr(feature = "sqlx", repr(i16))]
#[repr(u8)]
/// See <https://discord-userdoccers.vercel.app/resources/user#relationship-type>
pub enum RelationshipType {
Suggestion = 6,
Expand All @@ -58,3 +67,50 @@ pub enum RelationshipType {
Friends = 1,
None = 0,
}

#[cfg(feature = "sqlx")]
impl sqlx::Type<sqlx::Postgres> for RelationshipType {
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 RelationshipType {
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 RelationshipType {
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)?;
Self::try_from(sqlx_pg_uint.to_uint()).map_err(|e| e.into())
}
}

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

fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
6 => Ok(Self::Suggestion),
5 => Ok(Self::Implicit),
4 => Ok(Self::Outgoing),
3 => Ok(Self::Incoming),
2 => Ok(Self::Blocked),
1 => Ok(Self::Friends),
0 => Ok(Self::None),
_ => Err(ChorusError::InvalidArguments {
error: format!("Value {} is not a valid RelationshipType", value),
}),
}
}
}

0 comments on commit 8081352

Please sign in to comment.