Within the crate we can happily do something like this:
mod boundary {
pub struct EventLoop;
impl EventLoop {
pub fn run(&self) {
for _ in 0..2 {
self.handle("bundled");
self.foo();
}
}
pub fn handle(&self, message: &str) {
println!("{} handling", message)
}
}
pub trait EventLoopExtend {
fn foo(&self);
}
}
use boundary::EventLoopExtend;
impl EventLoopExtend for boundary::EventLoop {
fn foo(&self) {
self.handle("extended")
}
}
fn main() {
let el = boundary::EventLoop{};
el.run();
}
But if mod boundary were a crate boundary we get error[E0117]: only traits defined in the current crate can be implemented for arbitrary types.
I gather that a potential solution to this could be the New Type idiom, so something like this:
mod boundary {
pub struct EventLoop;
impl EventLoop {
pub fn run(&self) {
for _ in 0..2 {
self.handle("bundled");
self.foo();
}
}
pub fn handle(&self, message: &str) {
println!("{} handling", message)
}
}
pub trait EventLoopExtend {
fn foo(&self);
}
impl EventLoopExtend for EventLoop {
fn foo(&self) {
self.handle("unimplemented")
}
}
}
use boundary::{EventLoop, EventLoopExtend};
struct EventLoopNewType(EventLoop);
impl EventLoopExtend for EventLoopNewType {
fn foo(&self) {
self.0.handle("extended")
}
}
fn main() {
let el = EventLoopNewType(EventLoop {});
el.0.run();
}
But then the problem here is that the extended trait behaviour isn't accessible from the underlying EventLoop instance.
I'm still quite new to Rust, so I'm sure I'm missing something obvious, I wouldn't be surprised if I need to take a completely different approach.
Specifically in my case, the event loop is actually from wgpu, and I'm curious if it's possible to build a library where end users can provide their own "render pass" stage.