I'm working on a pre-existing project and need to add a field to structure Message which is a Box <dyn Any>.
Turning Box<dyn Any> into an enum is not possible for this project.
pub struct Message<PB: ProtocolBehavior> {
/* */
pub info: Box<dyn Any>,
}
Unfortunately, Message needs to be (de)serializable, and implement Hash, Clone, Debug, Display (the list goes on) ; therefore, so does the field info.
What I came up with was to create a new trait AnySerializable. I made it implement all traits necessary. (Thanks to dtolnay's typetag crate, I was able to make this new trait Serializable)
#[typetag::serde(tag = "type")]
pub trait AnySerializable: Any + core::fmt::Debug + std::fmt::Display + DynClone + DynHash {}
Then I modified the field info of Message.
pub struct Message<PB: ProtocolBehavior> {
/* */
pub info: Box<dyn AnySerializable>,
}
However, I need to be able to turn info into a Box<dyn Any>.
The following code gives me an error as the return types are mismatched.
impl Message {
pub fn get_info(&self) -> Box<dyn Any> {
self.info
}
}
So then I tried adding a method to my trait AnySerializable
#[typetag::serde(tag = "type")]
pub trait AnySerializable: Any + core::fmt::Debug + std::fmt::Display + DynClone + DynHash {
fn as_any(&self) -> dyn Any;
}
along with this method for Message.
impl Message {
pub fn get_info(&self) -> Box<dyn Any> {
Box::new(self.info.clone().as_ref().as_any())
}
}
However I can't box dyn Any as its size is not known at compilation time.
But I would like to do something like this. Is there a way to do this, possibly with unsafe Rust ?
I tried replacing any occurrence of Any by AnySerializable in the project, but I get additional errors that seem very complicated. I will look into them if I can't elegantly get a Box<dyn Any>.