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>
.