Compare commits

...

6 Commits

5 changed files with 114 additions and 41 deletions

View File

@ -11,6 +11,7 @@ use crate::types::utils::Snowflake;
use crate::types::Shared; use crate::types::Shared;
use crate::types::{Team, User}; use crate::types::{Team, User};
#[allow(unused_imports)]
use super::{arc_rwlock_ptr_eq, option_arc_rwlock_ptr_eq}; use super::{arc_rwlock_ptr_eq, option_arc_rwlock_ptr_eq};
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -87,13 +88,35 @@ impl PartialEq for Application {
&& self.discovery_eligibility_flags == other.discovery_eligibility_flags && self.discovery_eligibility_flags == other.discovery_eligibility_flags
&& self.tags == other.tags && self.tags == other.tags
&& self.cover_image == other.cover_image && self.cover_image == other.cover_image
&& option_arc_rwlock_ptr_eq(&self.install_params, &other.install_params) && compare_install_params(&self.install_params, &other.install_params)
&& self.terms_of_service_url == other.terms_of_service_url && self.terms_of_service_url == other.terms_of_service_url
&& self.privacy_policy_url == other.privacy_policy_url && self.privacy_policy_url == other.privacy_policy_url
&& self.team == other.team && self.team == other.team
} }
} }
#[cfg(not(tarpaulin_include))]
#[cfg(feature = "sqlx")]
fn compare_install_params(
a: &Option<sqlx::types::Json<InstallParams>>,
b: &Option<sqlx::types::Json<InstallParams>>,
) -> bool {
match (a, b) {
(Some(a), Some(b)) => a.encode_to_string() == b.encode_to_string(),
(None, None) => true,
_ => false,
}
}
#[cfg(not(tarpaulin_include))]
#[cfg(not(feature = "sqlx"))]
fn compare_install_params(
a: &Option<Shared<InstallParams>>,
b: &Option<Shared<InstallParams>>,
) -> bool {
option_arc_rwlock_ptr_eq(a, b)
}
impl Default for Application { impl Default for Application {
fn default() -> Self { fn default() -> Self {
Self { Self {

View File

@ -2,7 +2,8 @@
// 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::sync::Arc; #[allow(unused_imports)]
use super::option_vec_arc_rwlock_ptr_eq;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr}; use serde_repr::{Deserialize_repr, Serialize_repr};
@ -31,38 +32,55 @@ pub struct AuditLogEntry {
pub reason: Option<String>, pub reason: Option<String>,
} }
#[cfg(not(tarpaulin_include))]
impl PartialEq for AuditLogEntry { impl PartialEq for AuditLogEntry {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
let everything_else = self.target_id == other.target_id self.target_id == other.target_id
&& self.user_id == other.user_id && self.user_id == other.user_id
&& self.id == other.id && self.id == other.id
&& self.action_type == other.action_type && self.action_type == other.action_type
&& self.options == other.options && compare_options(&self.options, &other.options)
&& self.reason == other.reason; && self.reason == other.reason
// Compare the Vec<Shared<AuditLogChange>> separately, since Shared<T> doesn't implement PartialEq && compare_changes(&self.changes, &other.changes)
match (&self.changes, &other.changes) {
// If both are Some, compare the contents
(Some(self_changes), Some(other_changes)) => {
let mut changes_equal = true;
// Iterate over both Vecs and compare the Arc pointers. If any are different, the
// Vecs are not equal
for (self_change, other_change) in self_changes.iter().zip(other_changes.iter()) {
if !Arc::ptr_eq(self_change, other_change) {
changes_equal = false;
break;
}
}
everything_else && changes_equal
}
// If both are None, they're equal
(None, None) => everything_else,
// If one is Some and the other is None, they're not equal
_ => false,
}
} }
} }
#[cfg(not(tarpaulin_include))]
#[cfg(feature = "sqlx")]
fn compare_options(
a: &Option<sqlx::types::Json<AuditEntryInfo>>,
b: &Option<sqlx::types::Json<AuditEntryInfo>>,
) -> bool {
match (a, b) {
(Some(a), Some(b)) => a.encode_to_string() == b.encode_to_string(),
(None, None) => true,
_ => false,
}
}
#[cfg(not(tarpaulin_include))]
#[cfg(not(feature = "sqlx"))]
fn compare_options(a: &Option<AuditEntryInfo>, b: &Option<AuditEntryInfo>) -> bool {
a == b
}
#[cfg(not(tarpaulin_include))]
#[cfg(feature = "sqlx")]
fn compare_changes(
a: &sqlx::types::Json<Option<Vec<Shared<AuditLogChange>>>>,
b: &sqlx::types::Json<Option<Vec<Shared<AuditLogChange>>>>,
) -> bool {
a.encode_to_string() == b.encode_to_string()
}
#[cfg(not(tarpaulin_include))]
#[cfg(not(feature = "sqlx"))]
fn compare_changes(
a: &Option<Vec<Shared<AuditLogChange>>>,
b: &Option<Vec<Shared<AuditLogChange>>>,
) -> bool {
option_vec_arc_rwlock_ptr_eq(a, b)
}
#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[derive(Serialize, Deserialize, Debug, Default, Clone)]
/// See <https://discord.com/developers/docs/resources/audit-log#audit-log-change-object> /// See <https://discord.com/developers/docs/resources/audit-log#audit-log-change-object>
pub struct AuditLogChange { pub struct AuditLogChange {

View File

@ -27,6 +27,9 @@ use crate::gateway::Updateable;
use chorus_macros::{observe_option_vec, Composite, Updateable}; use chorus_macros::{observe_option_vec, Composite, Updateable};
use serde::de::{Error, Visitor}; 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};
#[derive(Default, Debug, Serialize, Deserialize, Clone)] #[derive(Default, Debug, Serialize, Deserialize, Clone)]
@ -98,6 +101,7 @@ pub struct Channel {
} }
#[cfg(not(tarpaulin_include))] #[cfg(not(tarpaulin_include))]
#[allow(clippy::nonminimal_bool)]
impl PartialEq for Channel { impl PartialEq for Channel {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.application_id == other.application_id self.application_id == other.application_id
@ -128,7 +132,7 @@ impl PartialEq for Channel {
&& self.nsfw == other.nsfw && self.nsfw == other.nsfw
&& self.owner_id == other.owner_id && self.owner_id == other.owner_id
&& self.parent_id == other.parent_id && self.parent_id == other.parent_id
&& option_vec_arc_rwlock_ptr_eq( && compare_permission_overwrites(
&self.permission_overwrites, &self.permission_overwrites,
&other.permission_overwrites, &other.permission_overwrites,
) )
@ -145,6 +149,28 @@ impl PartialEq for Channel {
} }
} }
#[cfg(not(tarpaulin_include))]
#[cfg(feature = "sqlx")]
fn compare_permission_overwrites(
a: &Option<Json<Vec<PermissionOverwrite>>>,
b: &Option<Json<Vec<PermissionOverwrite>>>,
) -> bool {
match (a, b) {
(Some(a), Some(b)) => a.encode_to_string() == b.encode_to_string(),
(None, None) => true,
_ => false,
}
}
#[cfg(not(tarpaulin_include))]
#[cfg(not(feature = "sqlx"))]
fn compare_permission_overwrites(
a: &Option<Vec<Shared<PermissionOverwrite>>>,
b: &Option<Vec<Shared<PermissionOverwrite>>>,
) -> bool {
option_vec_arc_rwlock_ptr_eq(a, b)
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
/// A tag that can be applied to a thread in a [ChannelType::GuildForum] or [ChannelType::GuildMedia] channel. /// A tag that can be applied to a thread in a [ChannelType::GuildForum] or [ChannelType::GuildMedia] channel.
/// ///

View File

@ -45,6 +45,7 @@ pub struct Emoji {
} }
#[cfg(not(tarpaulin_include))] #[cfg(not(tarpaulin_include))]
#[allow(clippy::nonminimal_bool)]
impl PartialEq for Emoji { impl PartialEq for Emoji {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.id == other.id self.id == other.id
@ -62,7 +63,7 @@ impl PartialEq for Emoji {
impl From<PartialEmoji> for Emoji { impl From<PartialEmoji> for Emoji {
fn from(value: PartialEmoji) -> Self { fn from(value: PartialEmoji) -> Self {
Self { Self {
id: value.id.unwrap_or_default(), // TODO: this should be handled differently id: value.id.unwrap_or_default(), // TODO: Make this method an impl to TryFrom<> instead
name: Some(value.name), name: Some(value.name),
roles: None, roles: None,
user: None, user: None,

View File

@ -142,13 +142,21 @@ impl<T: Sized> IntoShared for T {
} }
} }
/// Internal function to compare two `Arc<RwLock<T>>`s by comparing their pointers. /// Internal function to compare two `Shared<T>`s by comparing their pointers.
pub(crate) fn arc_rwlock_ptr_eq<T>(a: &Arc<RwLock<T>>, b: &Arc<RwLock<T>>) -> bool { #[cfg_attr(not(feature = "client"), allow(unused_variables))]
Arc::ptr_eq(a, b) pub(crate) fn arc_rwlock_ptr_eq<T>(a: &Shared<T>, b: &Shared<T>) -> bool {
#[cfg(feature = "client")]
{
Shared::ptr_eq(a, b)
}
#[cfg(not(feature = "client"))]
{
true
}
} }
/// Internal function to compare two `Vec<Arc<RwLock<T>>>`s by comparing their pointers. /// Internal function to compare two `Vec<Shared<T>>`s by comparing their pointers.
pub(crate) fn vec_arc_rwlock_ptr_eq<T>(a: &Vec<Arc<RwLock<T>>>, b: &Vec<Arc<RwLock<T>>>) -> bool { pub(crate) fn vec_arc_rwlock_ptr_eq<T>(a: &[Shared<T>], b: &[Shared<T>]) -> bool {
for (a, b) in a.iter().zip(b.iter()) { for (a, b) in a.iter().zip(b.iter()) {
if !arc_rwlock_ptr_eq(a, b) { if !arc_rwlock_ptr_eq(a, b) {
return false; return false;
@ -157,11 +165,8 @@ pub(crate) fn vec_arc_rwlock_ptr_eq<T>(a: &Vec<Arc<RwLock<T>>>, b: &Vec<Arc<RwLo
true true
} }
/// Internal function to compare two `Option<Arc<RwLock<T>>>`s by comparing their pointers. /// Internal function to compare two `Option<Shared<T>>`s by comparing their pointers.
pub(crate) fn option_arc_rwlock_ptr_eq<T>( pub(crate) fn option_arc_rwlock_ptr_eq<T>(a: &Option<Shared<T>>, b: &Option<Shared<T>>) -> bool {
a: &Option<Arc<RwLock<T>>>,
b: &Option<Arc<RwLock<T>>>,
) -> bool {
match (a, b) { match (a, b) {
(Some(a), Some(b)) => arc_rwlock_ptr_eq(a, b), (Some(a), Some(b)) => arc_rwlock_ptr_eq(a, b),
(None, None) => true, (None, None) => true,
@ -169,10 +174,10 @@ pub(crate) fn option_arc_rwlock_ptr_eq<T>(
} }
} }
/// Internal function to compare two `Option<Vec<Arc<RwLock<T>>>>`s by comparing their pointers. /// Internal function to compare two `Option<Vec<Shared<T>>>`s by comparing their pointers.
pub(crate) fn option_vec_arc_rwlock_ptr_eq<T>( pub(crate) fn option_vec_arc_rwlock_ptr_eq<T>(
a: &Option<Vec<Arc<RwLock<T>>>>, a: &Option<Vec<Shared<T>>>,
b: &Option<Vec<Arc<RwLock<T>>>>, b: &Option<Vec<Shared<T>>>,
) -> bool { ) -> bool {
match (a, b) { match (a, b) {
(Some(a), Some(b)) => vec_arc_rwlock_ptr_eq(a, b), (Some(a), Some(b)) => vec_arc_rwlock_ptr_eq(a, b),