- I am 100% sure that for
enum Animal
below, I want an enum, not a Trait. I want to define upfront the set of all possible valid values.
use super::*;
trait SomeT {
fn func1(&self);
fn func2(&self, x: isize);
fn func3(&self, y: u32);
fn func4(&self);
fn func5(&self);
}
pub struct Cat {}
pub struct Dog {}
pub struct Bird {}
pub struct Rat {}
impl SomeT for Cat {
fn func1(&self) { unimplemented!() }
fn func2(&self, x: isize) { unimplemented!() }
fn func3(&self, y: u32) { unimplemented!() }
fn func4(&self) { unimplemented!() }
fn func5(&self) { unimplemented!() }
}
impl SomeT for Dog {
fn func1(&self) { unimplemented!() }
fn func2(&self, x: isize) { unimplemented!() }
fn func3(&self, y: u32) { unimplemented!() }
fn func4(&self) { unimplemented!() }
fn func5(&self) { unimplemented!() }
}
impl SomeT for Bird {
fn func1(&self) { unimplemented!() }
fn func2(&self, x: isize) { unimplemented!() }
fn func3(&self, y: u32) { unimplemented!() }
fn func4(&self) { unimplemented!() }
fn func5(&self) { unimplemented!() }
}
impl SomeT for Rat {
fn func1(&self) { unimplemented!() }
fn func2(&self, x: isize) { unimplemented!() }
fn func3(&self, y: u32) { unimplemented!() }
fn func4(&self) { unimplemented!() }
fn func5(&self) { unimplemented!() }
}
// == ^^^^^ I have some Trait, and a bunch of structs that implement it. ^^^^^
pub enum Animal { // == Yes, I really do want a enum, instead of a Trait
Cat(Cat),
Dog(Dog),
Bird(Bird),
Rat(Rat),
}
// === is there someway to simplify these impls, this seems very repetitive
impl SomeT for Animal {
fn func1(&self) {
match self {
Animal::Cat(cat) => cat.func1(),
Animal::Dog(dog) => dog.func1(),
Animal::Bird(bird) => bird.func1(),
Animal::Rat(rat) => rat.func1(),
}
}
fn func2(&self, x: isize) {
match self {
Animal::Cat(cat) => cat.func2(x),
Animal::Dog(dog) => dog.func2(x),
Animal::Bird(bird) => bird.func2(x),
Animal::Rat(rat) => rat.func2(x),
}
}
fn func3(&self, y: u32) {
match self {
Animal::Cat(cat) => cat.func3(y),
Animal::Dog(dog) => dog.func3(y),
Animal::Bird(bird) => bird.func3(y),
Animal::Rat(rat) => rat.func3(y),
}
}
fn func4(&self) {
match self {
Animal::Cat(cat) => cat.func4(),
Animal::Dog(dog) => dog.func4(),
Animal::Bird(bird) => bird.func4(),
Animal::Rat(rat) => rat.func4(),
}
}
fn func5(&self) {
match self {
Animal::Cat(cat) => cat.func5(),
Animal::Dog(dog) => dog.func5(),
Animal::Bird(bird) => bird.func5(),
Animal::Rat(rat) => rat.func5(),
}
}
}
- Is there some way to reduce this repetition? I guarantee that my
enum Animal
is a list of the form Name(StructName), where StructName implements Foot
.. and all I want enum Animal
to do is to "pass through the function cal"
1 Like
You could use macros to do this, there may also be a crate to handle this.
I had this exact same use case when working with ASTs and compilers. You can use defer!()
from the sum_type crate to do the passthrough stuff. The sum_type!()
macro also adds a bunch of convenience methods and impls for converting to/from the variant types.
2 Likes
@Michael-F-Bryan : defer!
is indeed what I am looking for. Thanks!