How do you assert enums?


#1

I have an enum for Opcodes, like so:

enum Opcode {
  Add,
  Sub,
  Mul,
  Div,
  etc...
};

And I’m trying to test that a struct containing the opcode as a field has the correct enum. How do I assert it in a test? The following doesn’t work.

fn x_n_test() {
    let node = x_n();
    assert_eq!(node.opcode, Opcode::X);
}

#2

assert_eq! needs (naturally) an == operator, thus also an PartialEq implementation for operands. For enums, prepending #[derive(PartialEq)] is the easiest way to get it.


#3

I’m pretty new to Rust. While it makes sense I need to implement a == operator, I’m not sure what you mean by PartialEq implementation. Do you have a short example?


#4

Ah, probably that needs a knowledge about traits. :slight_smile: If you don’t know about traits, for now, you can just assume that == needs the following:

#[derive(PartialEq)] // <- this line has been added
enum Opcode {
    ...
}

(You can also get > or < with #[derive(PartialOrd)]. There are tons of other things like this available with #[derive]. Not every enum can be empowered with this way though, and that’s when you need to understand traits…)


#5

Ah, it’s like a preprocessor that adds methods. I’ll look into derives. Thanks for the lead!


#6

There’s also a matches! macro in the matches crate:

assert!(matches!(node.opcode, Opcode::X));

#7

Nice! But with it, I get an error.

src/libfab/tree/node.rs:603:51: 603:52 error: unexpected end of macro invocation
src/libfab/tree/node.rs:603         assert_eq!(matches!(node.opcode, Opcode::X));
                                                                              ^

Seems to be pointing to the second to last parens.


#8

Sorry, I meant assert!. The unfortunate problem with macros is that the error messages are terrible. Also, it appears you need to import the _tt_as_expr_hack macro as well…

#[macro_use(matches, _tt_as_expr_hack)]
extern crate matches;

enum Opcode {
    X,
    Y,
}

#[test]
fn it_works() {
    assert!(matches!(Opcode::X, Opcode::X));
}