pub trait Reflectable<C = DefaultConfig>:
Send
+ Sync
+ 'static {
// Required methods
fn reflect(self) -> Envelope;
fn reflect_ref(&self) -> EnvelopeRef<'_>;
fn reflect_mut(&mut self) -> EnvelopeMut<'_>;
}Expand description
Trait for types that know how to reflect themselves.
Provides owned, shared, and mutable reflection — analogous to how
Any provides downcast, downcast_ref, and downcast_mut.
The generic parameter C is a config marker — it allows multiple implementations
of Reflectable for the same type with different probing configurations. More importantly,
it lets downstream crates dodge the orphan rule: define your own config type (which is local
to your crate), then implement Reflectable<MyConfig> for any type — even types from
upstream crates.
§Manual Implementation
struct MyEvent { data: String }
impl Reflectable for MyEvent {
fn reflect(self) -> Envelope { reflect!(self) }
fn reflect_ref(&self) -> EnvelopeRef<'_> { reflect_ref!(&*self) }
fn reflect_mut(&mut self) -> EnvelopeMut<'_> { reflect_mut!(&mut *self) }
}§Using the Helper Macro
struct MyEvent { data: String }
impl_reflectable!(MyEvent);
// With custom registries:
struct OtherEvent;
impl_reflectable!(OtherEvent, { registries: [{ registry: MyRegistry, slots: 0..5 }] });§Orphan Rule Dodge
// Upstream crate defines a type:
struct UpstreamEvent { data: String }
// Your crate defines a config marker:
struct MyConfig;
// Now you can impl Reflectable<MyConfig> for UpstreamEvent — no orphan violation!
impl_reflectable!(UpstreamEvent, { config: MyConfig });
// A library function generic over config:
fn process<C>(event: impl Reflectable<C>) {
let envelope = event.reflect();
// ...
}