Exercise 5: A More Complex Example

In this task, we'll be implementing code to make the following syntax possible:

fn main() { for_2d!(row <i32> in 1..5, col <i32> in 2..7, { // code }); }

Ignoring extra curly braces, this code should translate to

fn main() { for row in 1..5 { let row: i32 = row; for col in 2..7 { let col: i32 = col; // code } } }

Note that the names of the variables may change (i.e. they could be row and col, or x and y, or something else).

To complete this task, there more fragment specifiers you will need to know about:

  • ident: an "identifier", like a variable name. ident metavariables Can be followed by anything.
  • block: a "block expression" (curly braces, and their contents). Can be followed by anything.
  • ty: a type. Can only be followed by =>, ,, =, |, ;, :, >, >>, [, {, as, where, or a block metavariable.

As a reminder, you may not edit the main function, but it should eventually look like the following:

fn main() { for row in 1..5 { let row: i32 = row; for col in 2..7 { let col: i32 = col; { (Coordinate { x: col, y: row }).show() } } } let values = [1, 3, 5]; for x in values { let x: u16 = x; for y in values { let y: u16 = y; { (Coordinate { x: x.into(), y: y.into(), }) .show() } } } }