Add TryPartialEq trait to check for equality

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 3 years ago
parent 55c2d41040
commit 5e5b1d8f6d
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,6 +1,6 @@
[package] [package]
name = "multi-trait-object" name = "multi-trait-object"
version = "0.1.2" version = "0.1.3"
edition = "2021" edition = "2021"
readme = "README.md" readme = "README.md"
license = "Apache-2.0" license = "Apache-2.0"

@ -26,7 +26,7 @@ impl ChangeStruct for TestStruct {
} }
} }
impl_trait_object!(TestStruct, dyn RawClone, dyn ChangeStruct, dyn Debug); impl_trait_object!(TestStruct, dyn RawClone, dyn PartialEqAny, dyn ChangeStruct, dyn Debug);
#[test] #[test]
fn it_creates_fat_pointers() { fn it_creates_fat_pointers() {
@ -95,3 +95,12 @@ fn it_returns_type_information() {
assert!(mto.implements::<dyn Debug>()); assert!(mto.implements::<dyn Debug>());
assert!(mto.implements::<dyn ChangeStruct>()); assert!(mto.implements::<dyn ChangeStruct>());
} }
#[test]
fn it_tries_partial_eq() {
let mto = TestStruct::default().into_multitrait();
let mto_eq = TestStruct::default().into_multitrait();
let mto_neq = TestStruct {test: String::from("no"), a: 6}.into_multitrait();
assert!(mto.try_eq(&mto_eq).unwrap());
assert_eq!(mto.try_eq(&mto_neq).unwrap(), false);
}

@ -1,5 +1,7 @@
mod try_clone; mod try_clone;
mod debug; mod debug;
mod try_partial_eq;
pub use try_clone::*; pub use try_clone::*;
pub use debug::*; pub use debug::*;
pub use try_partial_eq::*;

@ -15,14 +15,15 @@ pub unsafe trait RawClone {
unsafe fn raw_clone(&self) -> *mut (); unsafe fn raw_clone(&self) -> *mut ();
} }
/// A trait that tries cloning an object and returns an option
/// with the variant depending on the result. For a multitrait object
/// to be clonable it needs to have the [RawClone] trait registered.
unsafe impl<T: Clone> RawClone for T { unsafe impl<T: Clone> RawClone for T {
unsafe fn raw_clone(&self) -> *mut () { unsafe fn raw_clone(&self) -> *mut () {
Box::into_raw(Box::new(self.clone())) as *mut () Box::into_raw(Box::new(self.clone())) as *mut ()
} }
} }
/// A trait that tries cloning an object and returns an option
/// with the variant depending on the result.
impl TryClone for MultitraitObject { impl TryClone for MultitraitObject {
fn try_clone(&self) -> Option<Self> { fn try_clone(&self) -> Option<Self> {
let clone = self.downcast_trait::<dyn RawClone>()?; let clone = self.downcast_trait::<dyn RawClone>()?;

@ -0,0 +1,37 @@
use std::any::{Any};
use crate::MultitraitObject;
/// Compares the given value with an Any trait object.
/// Register this trait if you want to compare two Multitrait objects
/// with the [TryPartialEq] trait.
pub trait PartialEqAny {
fn partial_equal_any(&self, other: &dyn Any) -> bool;
}
impl<T: PartialEq + Any> PartialEqAny for T {
fn partial_equal_any(&self, other: &dyn Any) -> bool {
if let Some(other) = other.downcast_ref::<T>() {
self.eq(other)
} else {
false
}
}
}
/// Tries to compare the MultitraitObject with another object
/// and returns Some(bool) when the underlying type implements PartialEq and
/// has the [PartialEqAny] trait registered on the object.
pub trait TryPartialEq {
fn try_eq(&self, other: &Self) -> Option<bool>;
}
impl TryPartialEq for MultitraitObject {
fn try_eq(&self, other: &Self) -> Option<bool> {
if let Some(eq_any) = self.downcast_trait::<dyn PartialEqAny>() {
let any = other.downcast_trait::<dyn Any>().unwrap();
Some(eq_any.partial_equal_any(any))
} else {
None
}
}
}
Loading…
Cancel
Save