10

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);
Ömer Erden
  • 7,680
  • 5
  • 36
  • 45
Paul Stone
  • 109
  • 1
  • 4
  • 4
    Or this? [Unwrap inner type when enum variant is known](https://stackoverflow.com/questions/34953711/unwrap-inner-type-when-enum-variant-is-known) – Lukas Kalbertodt Mar 24 '20 at 07:34
  • 1
    I encourage you to re-read [*The Rust Programming Language*](https://doc.rust-lang.org/book/), especially the [chapter on enums](https://doc.rust-lang.org/book/ch06-00-enums.html). These Rust fundamentals are well-covered by existing material. – Shepmaster Mar 24 '20 at 13:56
  • @Lukas, I had seen your solution, but you didn't actually explain the syntax, and I couldn't wrap my brain around it. I tried again today, and I think I have something which appears to be working, although I still don't understand the syntax. – Paul Stone Mar 24 '20 at 20:22
  • I have spent hours trying to figure this out, googling and trying various solutions. I have by no means posted everything I tried. To have this closed is extremely frustrating. I appreciate @Lukas responding, although I had already seen his solution when I posted this question. – Paul Stone Mar 24 '20 at 20:28
  • This was a waste of my time. – Paul Stone Mar 24 '20 at 20:29
  • 1
    @PaulStone don't consider this as a waste of time, maybe your next question should be why this syntax works? Please check, I wrote an answer about this: https://stackoverflow.com/questions/53901550/what-does-some-do-on-the-left-hand-side-of-a-variable-assignment/53902304#53902304, if you still have questions after reading please ask, good luck. – Ömer Erden Mar 24 '20 at 21:20
  • Thanks, @Omer. I appreciate the response. That's a nice explanation. Additionally, I did get some help in another forum, and confirmation that my syntax (derived from Lukas' solution) is a reasonable approach. – Paul Stone Mar 26 '20 at 01:20

0 Answers0