From 111a8c42f5ea8a7afcd1b7f59cd93486d05c8454 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 26 Jul 2024 14:54:55 +0200 Subject: [PATCH 1/3] change theme_colors from Vec to (u32, u32) --- src/types/entities/user.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 81978b0..e3cf5ce 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -61,7 +61,7 @@ pub struct User { pub public_flags: Option, pub banner: Option, pub bio: Option, - pub theme_colors: Option>, + pub theme_colors: Option<(u32, u32)>, pub phone: Option, pub nsfw_allowed: Option, pub premium: Option, @@ -78,7 +78,7 @@ pub struct PublicUser { pub avatar: Option, pub accent_color: Option, pub banner: Option, - pub theme_colors: Option>, + pub theme_colors: Option<(u32, u32)>, pub pronouns: Option, pub bot: Option, pub bio: Option, From ffcf15d058d9b629c0e842efc02192421c498d33 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 26 Jul 2024 17:30:12 +0200 Subject: [PATCH 2/3] Custom ThemeColors type with sqlx::Encode and sqlx::Decode impls --- src/types/entities/user.rs | 67 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index e3cf5ce..6dae5c4 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -2,10 +2,12 @@ // 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/. +use crate::errors::ChorusError; use crate::types::utils::Snowflake; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; +use std::array::TryFromSliceError; use std::fmt::Debug; #[cfg(feature = "client")] @@ -61,7 +63,7 @@ pub struct User { pub public_flags: Option, pub banner: Option, pub bio: Option, - pub theme_colors: Option<(u32, u32)>, + pub theme_colors: Option, pub phone: Option, pub nsfw_allowed: Option, pub premium: Option, @@ -70,6 +72,65 @@ pub struct User { pub disabled: Option, } +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Copy)] +pub struct ThemeColors { + #[serde(flatten)] + inner: (u32, u32), +} + +impl TryFrom> for ThemeColors { + type Error = ChorusError; + + fn try_from(value: Vec) -> Result { + if value.len() % 4 != 0 || value.len() > 8 { + return Err(ChorusError::InvalidArguments { + error: "Value has incorrect length to be decodeable from Vec".to_string(), + }); + } + let first: Result<[u8; 4], TryFromSliceError> = value[0..3].try_into(); + let second: Result<[u8; 4], TryFromSliceError> = { + if value.len() == 8 { + value[0..3].try_into() + } else { + [0; 4][0..3].try_into() + } + }; + + match (first, second) { + (Ok(first), Ok(second)) => Ok(Self { + inner: (u32::from_be_bytes(first), u32::from_be_bytes(second)), + }), + _ => Err(ChorusError::InvalidArguments { + error: "ThemeColors cannot be built from this Vec".to_string(), + }), + } + } +} + +#[cfg(feature = "sqlx")] +// TODO: Add tests for Encode and Decode. +impl<'q> sqlx::Encode<'q, sqlx::MySql> for ThemeColors { + fn encode_by_ref( + &self, + buf: &mut >::ArgumentBuffer, + ) -> sqlx::encode::IsNull { + let mut vec_u8 = Vec::new(); + vec_u8.extend_from_slice(&self.inner.0.to_be_bytes()); + vec_u8.extend_from_slice(&self.inner.1.to_be_bytes()); + as sqlx::Encode<'q, sqlx::MySql>>::encode_by_ref(&vec_u8, buf) + } +} + +#[cfg(feature = "sqlx")] +impl<'d> sqlx::Decode<'d, sqlx::MySql> for ThemeColors { + fn decode( + value: >::ValueRef, + ) -> Result { + let value_vec = as sqlx::Decode<'d, sqlx::MySql>>::decode(value)?; + value_vec.try_into().map_err(|e: ChorusError| e.into()) + } +} + #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)] pub struct PublicUser { pub id: Snowflake, @@ -78,7 +139,7 @@ pub struct PublicUser { pub avatar: Option, pub accent_color: Option, pub banner: Option, - pub theme_colors: Option<(u32, u32)>, + pub theme_colors: Option, pub pronouns: Option, pub bot: Option, pub bio: Option, @@ -144,7 +205,7 @@ pub struct UserProfileMetadata { pub bio: Option, pub banner: Option, pub accent_color: Option, - pub theme_colors: Option>, + pub theme_colors: Option, pub popout_animation_particle_type: Option, pub emoji: Option, } From 9dbb5ea77b7e323c50fbfb8ea3b7dfdd79ec652c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 26 Jul 2024 17:40:42 +0200 Subject: [PATCH 3/3] impl sqlx::Type for ThemeColors --- src/types/entities/user.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 6dae5c4..674c931 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -131,6 +131,13 @@ impl<'d> sqlx::Decode<'d, sqlx::MySql> for ThemeColors { } } +#[cfg(feature = "sqlx")] +impl sqlx::Type for ThemeColors { + fn type_info() -> ::TypeInfo { + >::type_info() + } +} + #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)] pub struct PublicUser { pub id: Snowflake,