After chatting with @tamarafischer and @stevenhartley and reading through the equivalent PR over on up-java, I tried my hand at something similar over here in Rust.
This is very much in draft status to garner feedback! :slightly_smiling_face:
Some Design Considerations
(examples shamelessly ctrl+c, ctrl+v'ed from Chat-Gippity)
pub trait SuperTrait {
// Method for accepting a visitor. The visitor is an implementation of
// a trait that will perform operations specific to the type of the object.
fn accept(&self, visitor: &dyn Visitor);
}
pub trait SubTrait1: SuperTrait {}
pub trait SubTraitN: SuperTrait {}
pub trait Visitor {
fn visit_sub_trait1(&self, element: &dyn SubTrait1);
fn visit_sub_trait_n(&self, element: &dyn SubTraitN);
// Add methods for other subtraits as needed
}
struct ConcreteSubTrait1;
impl SuperTrait for ConcreteSubTrait1 {
fn accept(&self, visitor: &dyn Visitor) {
visitor.visit_sub_trait1(self);
}
}
impl SubTrait1 for ConcreteSubTrait1 {}
struct ConcreteSubTraitN;
impl SuperTrait for ConcreteSubTraitN {
fn accept(&self, visitor: &dyn Visitor) {
visitor.visit_sub_trait_n(self);
}
}
impl SubTraitN for ConcreteSubTraitN {}
struct MyVisitor;
impl Visitor for MyVisitor {
fn visit_sub_trait1(&self, _element: &dyn SubTrait1) {
println!("SubTrait1 visited");
}
fn visit_sub_trait_n(&self, _element: &dyn SubTraitN) {
println!("SubTraitN visited");
}
// Implement other visit methods as needed
}
Pros
Leans more on Rust's type system
Cons
A lot of boiler-plate!
Not as flexible as Downcasting + Any
New categories of listener added imply a library change + change to all downstream users (unless they did a pattern match with a _ match arm to discard any unknown types...?)
Enum containing trait objects (the solution in this PR)
Pros
Leans on Rust's type system to prevent most compile time issues
Less boilerplate than Visitor pattern
Cons
Not as flexible as Downcasting + Any
New categories of listener added imply a library change + change to all downstream users (unless they did a pattern match with a _ match arm to discard any unknown types...?)
Hey there folks :wave:
After chatting with @tamarafischer and @stevenhartley and reading through the equivalent PR over on
up-java
, I tried my hand at something similar over here in Rust.This is very much in draft status to garner feedback! :slightly_smiling_face:
Some Design Considerations
(examples shamelessly ctrl+c, ctrl+v'ed from Chat-Gippity)
Downcasting + Any
Pros:
Cons:
TypeTag / Discriminants
Pros:
Cons:
Visitor Pattern
Pros
Cons
_
match arm to discard any unknown types...?)Enum containing trait objects (the solution in this PR)
Pros
Cons
_
match arm to discard any unknown types...?)