radionnazmiev
radionnazmiev

Reputation: 162

How can I declare a variable within a match statement branches?

I'm trying to solve a task from https://www.codewars.com/kata/591588d49f4056e13f000001/train/rust

Your task is to implement an simple interpreter for the notorious esoteric language HQ9+ that will work for a single character input:

  • If the input is 'H', return 'Hello World!'
  • If the input is 'Q', return the input
  • If the input is '9', return the full lyrics of 99 Bottles of Beer.

I can't get it to work for some reason. I don't know what I'm missing out on in here. How can I declare a variable within a match statement branches?

fn hq9(code: &str) -> Option<String> {
    match code{
        "H" => Some("Hello World!".to_string()),
        "Q" => Some("Q".to_string()),
        "9" => let s = String::new();
        (0..=99).rev().for_each(|x|
                                match x {
                                    x @ 3..=99 => s.push_str("{} bottles of beer on the wall, {} bottles of beer.\nTake one down and pass it around, {} bottles of beer on the wall.\n",x,x,x-1),
                                    2 => s.push_str("2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n"),
                                    1 => s.push_str("1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n"),
                                    0 => s.push_str("No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"),
                                    _ => panic!(),
                                })
            Some(s),
        _  => None,
    }
}

Upvotes: 0

Views: 918

Answers (1)

kmdreko
kmdreko

Reputation: 60272

The match arms use the syntax PATTERN => EXPRESSION, if the expression needs multiple statements, use a block {}:

fn hq9(code: &str) -> Option<String> {
    match code {
        "H" => Some("Hello World!".to_string()),
        "Q" => Some("Q".to_string()),
        "9" => { // <----------------- start block
            let s = String::new();
            (0..=99).rev().for_each(|x|
                match x {
                    x @ 3..=99 => s.push_str("{} bottles of beer on the wall, {} bottles of beer.\nTake one down and pass it around, {} bottles of beer on the wall.\n",x,x,x-1),
                    2 => s.push_str("2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n"),
                    1 => s.push_str("1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n"),
                    0 => s.push_str("No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"),
                    _ => panic!(),
                });
            Some(s)
        } // <----------------- end block
        _  => None,
    }
}

Fixing this exposes other errors.

Upvotes: 3

Related Questions