I have been interested in trying Rust in a long time, and I finally got around to sit down and start reading "The Book". I have not finished yet, so there are probably a few features that I could have used, but I didn't know about.
Anyway, the purpose of this program is to generate a maze (using the simplest "Randomized DFS" algorithm).
Since the main goal for me was to practice the language, I tried to make the program as "idiomatic" as possible. The main thing that still bothers me is all those type conversions between the signed and unsigned types. Since this is my first Rust program, I am mainly just looking for feedback on anything that could be considered "bad code", or parts that could be improved in any way.
extern crate rand; extern crate image; use std::io::Write; use rand::Rng; #[derive(Clone, PartialEq)] enum Cell { Blocked, Free, } fn make_odd(mut t: (usize, usize)) -> (usize, usize) { let o = |v: &mut usize| if *v%2==0{*v+=1}; o(&mut t.0); o(&mut t.1); t } fn gen(s: (usize, usize)) -> Vec<Vec<Cell>> { let mut t = vec![vec![Cell::Blocked; s.1]; s.0]; let mut stack = Vec::<(isize, isize)>::new(); let c = make_odd((s.0/2, s.1/2)); stack.push((c.0 as isize, c.1 as isize)); t[c.0][c.1] = Cell::Free; let mut dirs: [(isize, isize); 4] = [(2, 0), (-2, 0), (0, 2), (0, -2)]; let mut rng = rand::thread_rng(); 'o: while let Some(&(x, y)) = stack.last() { rng.shuffle(&mut dirs); for i in 0..4 { let (dx, dy) = dirs[i]; let (nx, ny) = (x+dx, y+dy); if nx < 0 || ny < 0 || nx >= (s.0 as isize) || ny >= (s.1 as isize) { continue; } if t[nx as usize][ny as usize] != Cell::Free { stack.push((nx, ny)); t[nx as usize][ny as usize] = Cell::Free; t[(x+dx/2) as usize][(y+dy/2) as usize] = Cell::Free; continue 'o; } } stack.pop(); } t[0][1] = Cell::Free; t[s.0-1][s.1-2] = Cell::Free; t } fn print_usage() -> ! { let _ = writeln!(std::io::stderr(), "Usage: maze-gen width height [output.png]"); std::process::exit(1); } fn main() { let args: Vec<_> = std::env::args().collect(); if args.len() < 3 { print_usage(); } let mut nums = [0; 2]; for i in 0..2 { match args[i+1].parse::<usize>() { Err(_) => { print_usage(); }, Ok(v) => nums[i] = v, } } let s0 = (nums[0], nums[1]); let mut s = make_odd(s0); if s.0 < 3 { s.0 = 3; } if s.1 < 3 { s.1 = 3; } if s != s0 { let _ = writeln!(std::io::stderr(), "Warning: Adjusting sizes to {} and {}!", s.0, s.1); } let m = gen(s); let mut buf = image::ImageBuffer::new(s.0 as u32, s.1 as u32); for (x,y,px) in buf.enumerate_pixels_mut() { *px = image::Luma([ match m[x as usize][y as usize] { Cell::Free => 255, Cell::Blocked => 0, } ]); } let filename = if args.len() >= 4 { args[3].as_str() } else { "out.png" }; let ref mut file = std::fs::File::create(&std::path::Path::new(filename)).unwrap(); image::ImageLuma8(buf).save(file, image::PNG).unwrap(); } Sample output: (It's quite tiny, you might have to download it and zoom in to see it properly.) 
(Sorry for any bad grammar, English is not my native language.)