How do you cast a Rust variant enum to an underlying struct?

Viewed 3564

The bind() call below works for IPV4, but not for IPV6.

pub enum SocketAddr {
    V4(SocketAddrV4),
    V6(SocketAddrV6),
}

pub fn new<A: ToSocketAddrs>(local_addr: A, _: Option<u32>) -> io::Result<UdpConnector> {
    let mut addr = net::addr_from_trait(local_addr)?;
    debug!("Attempting to connect to {:?}", addr);
    UdpSocket::bind(addr).expect(&format!("Couldn't bind to address {:?}", addr))
}

I think that I need to set the scope_id for the SocketAddrV6. However, I don't have a SocketAddrV6, I only have a generic SocketAddr, which doesn't implement scope_id().

I can call is_ipv6() on that SocketAddr, in order to see what type it is. If it's IPV6, then in C language terms, I would like to cast to the underlying SocketAddrV6, so I can call set_scope_id() on it. Then I want to pass the resulting SocketAddr or SocketAddrV6 variable to bind().

What I have tried

The following apparently only works on primitive types:

let addr2 = addr as SocketAddrV6

If I try to do implicit conversion, I get a type mismatch error. I guess it's telling me that addr is an enum, not a SocketAddrV6 struct. I know that. How do I do a cast in Rust?

54 |             let addr2: SocketAddrV6 = addr; 
   |                        ------------   ^^^^ expected struct `std::net::SocketAddrV6`, found enum `std::net::SocketAddr`

And here is another conversion attempt. Same error.

55 |             let addr2 = SocketAddr::V6(addr);
   |                                        ^^^^ expected struct `std::net::SocketAddrV6`, found enum `std::net::SocketAddr`

Another try

    error[E0573]: expected type, found variant `SocketAddr::V6`
  --> src/net/connector.rs:52:33
   |
52 |             let addr2 = addr as SocketAddr::V6;
   |                                 ^^^^^^^^^^^^^^ not a type

Edit: Based on @Lukas solution, the following seems to compile, but I don't yet know whether it is doing what I want.

let mut addr2 = if let SocketAddr::V6(c) = addr {c} else { unreachable!() };
addr2.set_scope_id(2);
0 Answers
Related