Skip to content

Instantly share code, notes, and snippets.

@jcavat
Created October 11, 2019 18:15
Show Gist options
  • Save jcavat/0e4599b3919f32764669143c733e99a0 to your computer and use it in GitHub Desktop.
Save jcavat/0e4599b3919f32764669143c733e99a0 to your computer and use it in GitHub Desktop.
Pattern match on traits in Rust
struct Foo{ value: u32 }
struct Bar{ value: u32 }
trait Base<T> {
fn accept(&self, v: &dyn Visitor<Result = T>) -> T ;
}
impl <T>Base<T> for Foo {
fn accept(&self, v: &dyn Visitor<Result = T>) -> T {
v.visit_foo(&self)
}
}
impl <T>Base<T> for Bar {
fn accept(&self, v: &dyn Visitor<Result = T>) -> T {
v.visit_bar(&self)
}
}
trait Visitor {
type Result;
fn visit_foo(&self, foo: &Foo) -> Self::Result;
fn visit_bar(&self, bar: &Bar) -> Self::Result;
}
struct StringVisitor {}
impl Visitor for StringVisitor {
type Result = String;
fn visit_foo(&self, foo: &Foo) -> String {
format!("it was Foo: {:}!", foo.value)
}
fn visit_bar(&self, bar: &Bar) -> String {
format!("it was Bar: {:}!", bar.value)
}
}
fn test<T>(v: bool) -> Box<dyn Base<T>> {
if v {
Box::new(Foo{value: 5})
} else {
Box::new(Bar{value: 10})
}
}
fn main() {
let f = test(true);
println!("{:}", f.accept( &StringVisitor{} ));
}
@jcavat
Copy link
Author

jcavat commented Oct 11, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment