AnswerBun.com

Combining if let statements in Rust

Stack Overflow Asked by Deniz Basgoren on July 24, 2020

I have the following enum, which represents cells in a 2d game world

#[derive(Copy, Clone)]
enum Cell {
    Empty,
    Soil,
    Metal,
    Diamond(Falling),
    Boulder(Falling),
    Player,
    Enemy,
    Exit
}

where Falling is also an enum:

#[derive(Copy, Clone)]
enum Falling {
    True,
    False
}

I also have a second enum:

#[derive(Copy, Clone)]
enum PlayerInput {
    None,
    Up,
    Down,
    Left,
    Right
}

I want to implement the following logic in Rust, according to which a boolean called canMove will be set either true or false:

let cell; // is of type Cell
let input; // is of type PlayerInput

if cell is Player or Metal, FALSE
if cell is Boulder(_) or Diamond(_) and input is Down, FALSE
if cell is Boulder(NotFalling) and input is Up, FALSE
if cell is Boulder(_) and input is Right or Left, and oneMoreCondition(cell,input) is true, FALSE
otherwise TRUE

Now that if let statements don’t support && operators, I’m left with match statements, which will still require nested if let statements, and the resulting code will be less readable. What is the idiomatic way to solve this? Or perhaps I’m misusing enums. Please propose a better solution please

One Answer

You can use match and match the two variables as a tuple:

#[derive(Copy, Clone)]
enum Cell {
    Empty,
    Soil,
    Metal,
    Diamond(Falling),
    Boulder(Falling),
    Player,
    Enemy,
    Exit
}

#[derive(Copy, Clone)]
enum Falling {
    True,
    False
}

#[derive(Copy, Clone)]
enum PlayerInput {
    None,
    Up,
    Down,
    Left,
    Right
}

fn oneMoreCondition(cell: Cell, input: PlayerInput) -> bool {
    // Any arbitrary logic here.
    true
}

fn canMove(cell: Cell, input: PlayerInput) -> bool {
    match (cell, input) {
        (Cell::Player, _) | (Cell::Metal, _) => false,
        (Cell::Boulder(_), PlayerInput::Down) | (Cell::Diamond(_), PlayerInput::Down) => false,
        (Cell::Boulder(Falling::False), PlayerInput::Up) => false,
        (Cell::Boulder(_), PlayerInput::Right) | (Cell::Boulder(_), PlayerInput::Left) if oneMoreCondition(cell, input) => false,
        _ => true,
    }
}

fn main() {
    println!("{}", canMove(Cell::Player, PlayerInput::Left));
    println!("{}", canMove(Cell::Boulder(Falling::True), PlayerInput::Down));
    println!("{}", canMove(Cell::Boulder(Falling::False), PlayerInput::Up));
    println!("{}", canMove(Cell::Boulder(Falling::False), PlayerInput::Right));
    println!("{}", canMove(Cell::Enemy, PlayerInput::Left));
}

Output:

false
false
false
false
true

Correct answer by ruohola on July 24, 2020

Add your own answers!

Related Questions

How Can I Not Double Count Rows And Objects In My Query?

3  Asked on November 22, 2021 by ziegler199

       

Login with active directory

0  Asked on November 20, 2021 by artisan

       

External CSS not linking for all elements

1  Asked on November 20, 2021 by stratos-la

   

Why is ‘u{1D11E}’.charAt(0) not equal to ‘u{1D11E}’?

2  Asked on November 20, 2021 by json-prime

     

E: Unable to locate package python3-boto3

2  Asked on November 20, 2021 by rosi-darmawati

       

x and o in tic tac toe keeps alternating

0  Asked on November 20, 2021 by channee-mathmath

     

Remove using a button

2  Asked on November 20, 2021 by gastn

   

remove 0 and add ‘ ‘ in every number in pandas

1  Asked on November 20, 2021 by spt-hsb

   

nav-tabs doesn’t change on click

0  Asked on November 20, 2021 by beureu

     

Stick element on bottom on page scroll

3  Asked on November 20, 2021

         

Exchange each 100 in a dataframe for another value

1  Asked on November 20, 2021 by tarik-benrabah

     

GraphQL & Using a nested subscribe function

1  Asked on November 20, 2021 by u-rogel

   

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP