The next error the compiler throws at us is error: Zombie does not name a structure; clearly the code for the Zombie struct is not found. Because this struct also resides in the monsters module, the solution is easy: prefix Zombie with monsters::, like this:
let zmb1 = monsters::Zombie {health: 75, damage: 15};
Another error: struct `Zombie` is private makes it clear that we must mark the Zombie struct with pub like the following:
pub struct Zombie { ... }
Now we get an error on the line containing zmb1.noise():error: type `monsters::Zombie` does not implement any method in scope named `noise`. The accompanying help note explains what to do and why:
help: methods from traits can only be called if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it: help: candidate #1: use `monsters::Monster`
So, let's add this to the code:
extern crate monsters; use monsters::Monster;
The last error we have to solve occurs at the use line: error: trait `Monster` is private - source trait is private. Again, it is very logical; if we want to use a trait, it must be publicly visible:
pub trait Monster { ... }
Now cargo build is successful, and if we execute monsters the output is this:
Printing from crate monsters! Oh no, I hear: Aaargh! The Zombie bites! Your health lowers with 30 damage points. Zombie { health: 75, damage: 15 }
This makes it clear that the things we want to make visible in our module (or put it another way, that we want to export) must be annotated with pub; they form the interface our module exposes to the outside world.