use std::{
any::Any,
fmt::{self, Debug, Display, Formatter},
};
pub struct Whatever(Box<dyn WhateverImpl>);
trait WhateverImpl: Debug + Display + Any + Send + Sync {
fn clone_whatever(&self) -> Whatever;
fn eq_whatever(&self, other: &Whatever) -> bool;
}
impl<T> WhateverImpl for T
where
T: Debug + Display + Clone + PartialEq + Send + Sync + 'static,
{
fn clone_whatever(&self) -> Whatever {
Whatever(Box::new(self.clone()))
}
fn eq_whatever(&self, other: &Whatever) -> bool {
let Some(other) = other.as_any_ref().downcast_ref() else {
return false;
};
self.eq(other)
}
}
impl Clone for Whatever {
fn clone(&self) -> Self {
self.0.clone_whatever()
}
}
impl Debug for Whatever {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(&self.0, f)
}
}
impl Display for Whatever {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}
impl PartialEq for Whatever {
fn eq(&self, other: &Self) -> bool {
self.0.eq_whatever(other)
}
}
impl Whatever {
pub fn from<T: Debug + Display + Clone + PartialEq + Send + Sync + 'static>(
value: T,
) -> Whatever {
Self(Box::new(value))
}
pub fn into_any(self) -> Box<dyn Any + Send + Sync> {
self.0
}
pub fn as_any_ref(&self) -> &dyn Any {
&self.0
}
pub fn as_any_mut(&mut self) -> &mut dyn Any {
&mut self.0
}
}