How do I assert an enum is a specific variant if I don't care about its fields?

rust check if variable is enum variant
rust cast enum to variant
rust enum
rust enum associated function
rust enum tutorial
rust enum match
rust enum of enums
rust increment enum

I'd like to check enums with fields in tests while ignoring the actual value of the fields for now.

Consider the following example:

enum MyEnum {
    WithoutFields,
    WithFields { field: String },
}

fn return_with_fields() -> MyEnum {
    MyEnum::WithFields {
        field: "some string".into(),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn example() {
        assert_eq!(return_with_fields(), MyEnum::WithFields {..});
    }
}

playground

I'd like to use assert_eq! here, but the compiler tells me:

error: expected expression, found `}`
  --> src/lib.rs:18:64
   |
18 |         assert_eq!(return_with_fields(), MyEnum::WithFields {..});
   |                                                                ^ expected expression

This is similar to Why do I get an error when pattern matching a struct-like enum variant with fields?, but the solution does not apply in my case.

Of course, I can use match and do it myself, but being able to use assert_eq! would be less work.

A simple solution here would be to do the opposite assertion:

assert!(return_with_fields() != MyEnum::WithoutFields);

or even more simply:

assert_ne!(return_with_fields(), MyEnum::WithoutFields);

Of course if you have more members in your enum, you'll have to add more asserts to cover all possible cases.

Alternatively, and this what OP probably had in mind, since assert! just panics in case of failure, the test can use pattern matching and call panic! directly in case something is wrong:

match return_with_fields() {
    MyEnum::WithFields {..} => {},
    MyEnum::WithoutFields => panic!("expected WithFields, got WithoutFields"),
}

How do you assert enums?, I have an enum for Opcodes, like so: enum Opcode { Add, Sub, Mul, Div, etc. If you don't know about traits, for now, you can just assume that == needs the following deriving PartialEq is the best solution in this specific case, though another  The second one is the type of that variant, and it presumes the existence of another type (a struct or another enum, or perhaps a type alias) named Add, whose definition is not shown here. Note that the names for the variants do not need to be the same as the names of the types of those variants, that's just how the OP chose to name them.

Your original code can be made to work with a new macro:

macro_rules! is_enum_variant {
    ($v:expr, $p:pat) => (
        if let $p = $v { true } else { false }
    );
}

#[test]
fn example() {
    assert!(is_enum_variant!(return_with_fields(), MyEnum::WithoutFields {..}));
}

Personally, I tend to add methods to my enums:

fn is_with_fields(&self) -> bool {
    match self {
        MyEnum::WithFields { .. } => true,
        _ => false,
    }
}

I also tend to avoid struct-like enums and instead put in extra work:

enum MyEnum {
    WithoutFields,
    WithFields(WithFields),
}

struct WithFields { field: String }

impl MyEnum {
    fn is_with_fields(&self) -> bool {
        match self {
            MyEnum::WithFields(_) => true,
            _ => false,
        }
    }

    fn as_with_fields(&self) -> Option<&WithFields> {
        match self {
            MyEnum::WithFields(x) => Some(x),
            _ => None,
        }
    }

    fn into_with_fields(self) -> Option<WithFields> {
        match self {
            MyEnum::WithFields(x) => Some(x),
            _ => None,
        }
    }
}

I hope that some day, enum variants can be made into their own type to avoid this extra struct.

Rust Programming Cookbook: Explore the latest features of Rust , test_make_fn() { make_fn!(fail, {assert!(false)}); // nothing happens if we don't implementation: macro_rules! default_enum { ($name: ident, $($variant: ident  Please don't suggest things like implementing an enum X { X1, X2 } and using struct S { variant: X, str: String } etc. This is a simplified example, imagine having lots of other fields in variants, and wanting to move one field from one variant to another.

I'd use a macro like @Shepmaster proposed, but with more error reporting (like the existing assert! and assert_eq! macros:

macro_rules! assert_variant {
    ($value:expr, $pattern:pat) => ({
        let value = &$value;

        if let $pattern = value {} else {
            panic!(r#"assertion failed (value doesn't match pattern):
   value: `{:?}`,
 pattern: `{}`"#, value, stringify!($pattern))
        }
    })

    // TODO: Additional patterns for trailing args, like assert and assert_eq
}

Rust playground demonstrating this example

Media, Culture, and Mediality: New Insights into the Current State , other technical media—this, at least, is the assertion. This implies— if not a point of philosophy of history—at least a punch line of media history. can be met by human beings only with computer literacy if they don't want to seem analphabets. The enumeration of variants has shown that the 'coding' of the term 'medium'  Matching on enum variant So, this code is what I want to achieve (the consume function, the rest is just for context), the problem with it is that it doesn't compile :). I know I could use structs implementing a common trait, to solve one of my problems (i.e. enum variants aren't real types of their own), but how can I match on a generic type?

Rust Package Registry, to a variant. If this value is omitted, then message will be used in it's place. props(key="value") : Enables associating additional information with a given variant. For VariantEq specifically we just need the enum identifier, and the variants of the enum. Next, we construct the list of variants. This is essentially a mapping of each enum variant into our EnumVariant type which can be used to generate tokens. More on that soon.

Groovy Truth, It could be that you don't care about the type at compile time or are relying on type inference (with Groovy's static nature). given: def x = 1 def y = 2 when: def z = x+y then: assert z == 3 Groovy allows transparent String (or GString ) to enum values coercion. So at runtime, o is a String so the String variant is used. I gave an answer to this here, on a different topic.It's a different style of approach which allows most of the same functionality without requiring modification to the original enum definition (and consequently allowing usage in cases where you don't define the enum).

Matching on enum variant : rust, enum Token { Name(String), OpeningBrace, ClosingBrace } fn next() Feels like you don't need generics here at all. level 2. agares3. Original Poster1 point · 1 year ago. Then how can I pass the specific variant of the enum to the function? None } fn main() { assert_eq!( consume::<Foo>().unwrap(), Token::Foo(Foo) ); }. If you don't want to type the values, use the following shortcut: class Animal(Enum): DOG, CAT = range(2) Enum implementations can be converted to lists and are iterable. The order of its members is the declaration order and has nothing to do with their values. For example:

Comments
  • What MyEnum::WithFields {..} is suppose to do ? play.rust-lang.org/…
  • Hi :) I think your question is answered by "Compare enums only by variant, not value". In short: use mem::discriminant. If you don't think this link answers your question, please explain why your question is different.
  • @Stargateur it is supposed to ignore the fields value and just match on WithFields.
  • @LukasKalbertodt Sadly that does not work, the rust compiler still wants me to specify the field somehow.
  • @PhilippLudwig You can't compare a variant with something that doesn't exist, do you want something like that ? play.rust-lang.org/…
  • Thanks, that is a good idea. I'm still wondering though if there is a more straight-forward solution. Or maybe I will just have to create my own macro.
  • @SirDarius Thanks for providing the source, this is interesting. I will accept your answer, maybe you want to include these additional information there.