pub trait Animal {
fn feed(&self) -> &str {
"yerp"
}
fn make_noise(&self) {}
fn lives_in(&self) {}
}
pub trait Herbivore {
fn eats(&self) {}
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct Dog {
pub name: String,
pub age: u8,
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct Cow {
pub name: String,
pub weight: u8,
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct Elephant {
name: String,
tusk_size: f32,
}
impl Animal for Dog {
fn lives_in(&self) {
println!("House");
}
fn make_noise(&self) {
println!("whow!");
}
}
impl Animal for Elephant {
fn lives_in(&self) {
println!("Forest");
}
fn make_noise(&self) {
println!("Yawwww");
}
}
impl Herbivore for Cow {
fn eats(&self) {
println!("grass");
}
}
impl Herbivore for Elephant {
fn eats(&self) {
println!("milk and grass");
}
}
fn display_animal<T, U>(first: &T, second: &U)
where
T: Animal + Herbivore,
U: Herbivore,
{
first.make_noise();
first.lives_in();
second.eats();
}
fn display_animal_second_approach(first: &(impl Animal + Herbivore), second: &impl Herbivore) {
first.make_noise();
first.lives_in();
second.eats();
}
fn display_animal_dyn_approach(first: &dyn Animal, second: &dyn Herbivore) {
first.make_noise();
first.lives_in();
second.eats();
}
#[allow(dead_code)]
pub fn impl_dyn() {
let dog = Dog {
name: "Mike".to_string(),
age: 2,
};
let cow = Cow {
name: "Yak".to_string(),
weight: 67,
};
let elephant = Elephant {
name: "Ronaldo".to_string(),
tusk_size: 2.1,
};
display_animal(&elephant, &cow);
display_animal_second_approach(&elephant, &cow);
display_animal_dyn_approach(&dog, &elephant);
}