Reputation: 2929
I have a module file (src/map/map.rs
):
type Layer = Vec<Vec<Tile>>;
pub struct Map {
height: i32,
width: i32,
data: Layer,
rooms: Vec<Rect>,
}
impl Map {
pub fn new(width: i32, height: i32) -> Self {
Map {
height: height,
width: width,
data: vec![vec![Tile::wall(); height as usize]; width as usize],
rooms: vec![Rect],
}
}
pub fn generate_with(&self, creator: module) {
creator::generate(&self)
}
}
a nested module map::gen::dungeon::basic
(src/map/gen/dungeon/basic.rs
)
with one function in the file:
pub fn generate(map: &mut Map) -> (Map, (i32, i32)) {}
and the map
module file (src/map/mod.rs
):
mod rect;
mod tile;
mod map;
pub mod room;
pub mod gen;
pub use self::map::Map;
pub use self::rect::Rect;
pub use self::tile::Tile;
imported into main.rs like this:
mod map;
use map::*;
use map::gen;
I want to be able to use it like this:
let (map, (player_x, player_y)) = Map::new(MAP_WIDTH, MAP_HEIGHT).generate_with(gen::dungeon::basic);
the error I get though is:
[cargo] expected value, found module 'gen::dungeon::basic': not a value [E]
A complete repo is available.
Upvotes: 3
Views: 1836
Reputation: 430981
As stated in the comments, a module is not a concrete concept like that; what you are attempting to do is not possible.
Instead, you can pass something that can be a value:
mod basic {
pub fn generate() -> u8 {
0
}
}
mod advanced {
pub fn generate() -> u8 {
42
}
}
fn play_the_game(generator: fn() -> u8) {
let dungeon = generator();
println!("{}", dungeon);
}
fn main() {
play_the_game(basic::generate);
play_the_game(advanced::generate);
}
You could also introduce a trait and pass the implementing type as a generic:
trait DungeonGenerator {
fn generate() -> u8;
}
mod basic {
use DungeonGenerator;
pub struct Basic;
impl DungeonGenerator for Basic {
fn generate() -> u8 {
0
}
}
}
mod advanced {
use DungeonGenerator;
pub struct Advanced;
impl DungeonGenerator for Advanced {
fn generate() -> u8 {
42
}
}
}
fn play_the_game<G>()
where
G: DungeonGenerator,
{
let dungeon = G::generate();
println!("{}", dungeon);
}
fn main() {
play_the_game::<basic::Basic>();
play_the_game::<advanced::Advanced>();
}
Upvotes: 9