I have a callback that gets called whenever two ports are connected/disconnected. I need to check if one of the ports is the port specified by my app (my_port) and turn that information into an event. It doesn't matter if my_port is port_a or port_b.
First I have done something like:
if port_a == my_port {
let event = if are_connected {
Event::OutPortConnected(port_b.to_string())
} else {
Event::OutPortDisconnected(port_b.to_string())
};
Some(event)
} else if port_b == my_port {
let event = if are_connected {
Event::OutPortConnected(port_a.to_string())
} else {
Event::OutPortDisconnected(port_a.to_string())
};
Some(event)
} else {
None
}
Then I came up with this:
let ports = [port_a, port_b];
let (src, dest): (Vec<&str>, Vec<&str>) =
ports.into_iter().partition(|p| *p == my_port);
if let (Some(_src), Some(dest)) = (src.first(), dest.first()) {
let event = match are_connected {
true => Event::OutPortConnected(dest.to_string()),
false => Event::OutPortDisconnected(dest.to_string()),
};
Some(event)
} else {
None
}
I think the first one is easier to understand, but could get confusing because of the boilerplate - I have do do this for an input port, too.
The second one is not bad, but I don't like the Vecs.
I think there might be a better way to accomplish this.
It's unfortunate that my_port in the pattern gets bound as a new variable shadowing the outer one. I was going to reply that the last example was my favorite, but found it had an unreachable match arm.
The updated version still looks OK though:
I like when a match can show you the 2 cases and their 2 outcomes on 2 easy to parse lines.
Thank you all for your suggestions, the solution from @derspiny and @danjl1100 worked best for me. I like that it preserves the natural order of first fetching the port and then producing the event.