Matching struct Enum member with an Option field

Hello, i have the following enum:

enum FlowChartNode {
    Squared           {id:String, label:Option<String>},
    Stadium           {id:String, label:Option<String>},
}

and I would like to match a FlowCharNode with the following:

impl Display for FlowChartNode {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 
        match self {
            FlowChartNode::Squared           {ref id, Some(label)} => write!(f, "{}", id),
            FlowChartNode::Stadium           {ref id, Some(label)} => write!(f, "{}", id),
        }
    }
}

I then receive the following error:

error: expected ,
|
| FlowChartNode::Squared {ref id, Some(label)} => write!(f, "{}", id),
| ---------------------- ^
| |
| while parsing the fields for this pattern

I also get the following but it definitely looks like a side effect:

error[E0425]: cannot find value id in this scope
|
33 | FlowChartNode::Squared {ref id, Some(label)} => write!(f, "{}", id),
| ^^ not found in this scope
|
help: consider importing this function
|
1 | use std::process::id;
|

I don't realize why my pattern is not valid, thank you for your help.

match self {
    FlowChartNode::Squared {ref id, label: Some(label)} => write!(f, "{}", id),
    //                 add this ----^^^^^^
    FlowChartNode::Stadium {ref id, label: Some(label)} => write!(f, "{}", id),
    //                 add this ----^^^^^^
}

The error message is needlessly confusing and could be better. The actual problem is that you have to give the field name explicitly except in the simplest case where you just bind the field to a variable of the same name. The pattern Some(label) does not "auto-match" the field label.

2 Likes

Binding to a variable with the same name as a field is a shorthand that works when infalliably matching the field, but not when conditionally matching within a subpattern like Some(_). You can do this:

    match self {
        FlowChartNode::Squared {ref id, label: Some(label)} => write!(f, "{}", id),
        FlowChartNode::Stadium {ref id, label: Some(label)} => write!(f, "{}", id),
    }

But given your implementation, perhaps consider this:

    match self {
        FlowChartNode::Squared {ref id, .. }
        | FlowChartNode::Stadium {ref id, .. } => write!(f, "{}", id),
    }
3 Likes

Thanks both of you for your quick answer.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.