-1

I have several enums:

enum Foo {
    A(A),
    B(B)
}

enum A {
    C(i32),
    D(i32)
}

enum B {
    E(i32),
    F(i32)
}

How could I write a function that takes a Foo and checks if it is, say, a B::E, then returns an Option<Foo>?

Edit: for clarification, the enum value is passed as an argument. I tried doing it with a signature of f(value: Foo, expected: Foo) but I'm not sure how to call that, as (with B::E again) the compiler wants an i32 supplied.

Herohtar
  • 5,347
  • 4
  • 31
  • 41
lolad
  • 321
  • 6
  • 13
  • 1
    This is pretty much day one of learning Rust. I suggest you read [The Rust Book](https://doc.rust-lang.org/book/) before you go any further or else you are going to be constantly needing to ask these simple questions, which are not useful to anyone else coming to Stackoverflow. – Peter Hall Oct 12 '20 at 15:58
  • Sorry, didn't clarify what I meant. – lolad Oct 12 '20 at 16:01
  • It would be helpful if you included a [mcve] that shows what you're trying to do, and the error you are getting. The way it is now, people just have to kind of guess at what you're attempting. – Herohtar Oct 13 '20 at 04:42

2 Answers2

2

You can't do it with a function, because function parameters must be complete values and the way you would express "variant E of enumeration B" is with a pattern. But you can do it with a macro, which can take patterns as arguments.

First here is how you would do it with a fixed pattern in a function:

fn filter_e (x: Foo) -> Option<Foo> {
    match x {
        Foo::B (B::E (_)) => Some (x),
        _ => None,
    }
}

Now if we want to make the pattern into a parameter, we need to wrap this code in a macro:

macro_rules! filter_foo {
    ($x:expr, $p:pat) => {{
        let x = $x;
        match x {
            $p => Some (x),
            _ => None,
        }
    }}
}

Which you then call like this:

filter_foo!(x, Foo::B (B::E (_)))

For more details on macros, see The Little Book of Rust Macros.

Jmb
  • 18,893
  • 2
  • 28
  • 55
0

I'm not sure if this answers the problem you're having, but you can use a match expression:

fn my_function(f: Foo) -> Option<Foo> {
    match f {
        Foo::B(B::E(_)) => { /* your code */ }
        _ => None // otherwise, return None
    }
}
Camelid
  • 1,535
  • 8
  • 21