How to use dynamic dispatch in Rust for trait with generics?

Viewed 185

I'm using a trait called RtspClient so I can create different Stream objects with different rtsp clients:

pub trait RtspClient {
    fn url(&self) -> Option<String>;
    fn username(&self) -> Option<String>;
    fn password(&self) -> Option<String>;
    fn connect(&self) -> Result<(), RtspClientError>;
    fn disconnect(&self) -> Result<(), RtspClientError>;
    fn set_on_produce<F: Fn(EncodedPacket)>(&self, f: F);
}

then I'm using it like this:

struct Stream {
    pub rtsp_client: Arc<Mutex<dyn RtspClient>>,
}

but I get the error that RtspClient cannot be used as an object because set_on_produce has generic types.

How can I use dynamic dispatch for rtsp_client and still be able to set closure callbacks with set_on_produce?

1 Answers

You can change the function's signature to accept:

  • A reference to a dyn, &dyn Fn(EncodedPacket),
  • A boxed dyn, Box<dyn Fn(EncodedPacket)>, useful for storing instead of (or in addition to) using immediately
  • A function pointer fn(EncodedPacket), which does not allow keeping track of state

See Advanced Functions and Closures.

You can also move the method to a different trait, and even have the other trait automatically implement the trait usable with dyn.

Playground demo

Related