I have events with a polymorphic payload property:
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
pub struct Event<'a> {
pub topic: String,
pub key: Option<String>,
pub payload: Box<dyn EventPayload<'a>>,
}
The only requirement for my payload, is that I want to serialize it using serde_json
:
pub trait EventPayload<'a> : Debug + Deserialize<'a> + Serialize {}
The compiler does not allow this pattern:
error[E0038]: the trait `EventPayload` cannot be made into an object
--> pong/src/event.rs:12:26
|
12 | pub payload: Box<dyn EventPayload<'a>>,
| ^^^^^^^^^^^^^^^^^^^^ `EventPayload` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
I know I could use enums for this use case:
enum Event {
EventA(EventAPayload),
EventB(EventBPayload),
}
However I don't like this solution because I would have to pin down types of objects that are defined outside of the application (e.g. by a schema registry).
What is the correct pattern to use in rust?