diff --git a/src/types/entities/relationship.rs b/src/types/entities/relationship.rs index 08cb41f1..e6d14f42 100644 --- a/src/types/entities/relationship.rs +++ b/src/types/entities/relationship.rs @@ -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 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, + #[cfg_attr(feature = "sqlx", sqlx(skip))] // Can be derived from the user id + /// The target user pub user: Shared, + /// When the user requested a relationship pub since: Option>, } @@ -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 pub enum RelationshipType { Suggestion = 6, @@ -58,3 +67,50 @@ pub enum RelationshipType { Friends = 1, None = 0, } + +#[cfg(feature = "sqlx")] +impl sqlx::Type for RelationshipType { + fn type_info() -> ::TypeInfo { + >::type_info() + } +} + +#[cfg(feature = "sqlx")] +impl<'q> sqlx::Encode<'q, sqlx::Postgres> for RelationshipType { + fn encode_by_ref( + &self, + buf: &mut ::ArgumentBuffer<'q>, + ) -> Result { + 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: ::ValueRef<'r>, + ) -> Result { + 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 for RelationshipType { + type Error = ChorusError; + + fn try_from(value: u8) -> Result { + 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), + }), + } + } +}