DEV Community

Fomalhaut Weisszwerg
Fomalhaut Weisszwerg

Posted on

How to overload function in Rust (Basic case).

Adapt version:

$ rustc --version
rustc 1.55.0 (c8dfcfe04 2021-09-06)
Enter fullscreen mode Exit fullscreen mode

To overload functions in Rust, "generics" is your friend.

use std::net:: {
    IpAddr,
    SocketAddr,
};

use socket2:: {
    Domain,
    Protocol,
    Socket,
    Type,
};

struct SampleStruct {
    ip_address: IpAddr,
    port_number: u16,
    sample_socket: socket2::Socket,
}

trait SampleTrait<T, O> {
    fn new(address:T, port:O) -> SampleStruct;
}

impl SampleTrait<String, u16> for SampleStruct {
    fn new(address: String, port: u16) -> Self {
        let addr = address.parse::<IpAddr>()
            .unwrap_or_else( |_| { panic!("`address` MUST be an IPv4 address (dotted-decimal form) or an IPv6 address.") });

        return SampleStruct {
            ip_address: addr,
            port_number: port,
            sample_socket: Socket::new(
                if addr.is_ipv4() { Domain::IPV4 } else { Domain::IPV6 },
                Type::DGRAM,
                Some(Protocol::UDP)
            ).unwrap()
        }
    }
}

impl SampleTrait<&str, u16> for SampleStruct {
    fn new(address: &str, port: u16) -> Self {
        let addr = address.to_string().parse::<IpAddr>()
            .unwrap_or_else( |_| { panic!("`address` MUST be an IPv4 address (dotted-decimal form) or an IPv6 address.") });

        return SampleStruct {
            ip_address: addr,
            port_number: port,
            sample_socket: Socket::new(
                if addr.is_ipv4() { Domain::IPV4 } else { Domain::IPV6 },
                Type::DGRAM,
                Some(Protocol::UDP)
            ).unwrap()
        }
    }
}

impl SampleTrait<IpAddr, u16> for SampleStruct {
    fn new(address: IpAddr, port: u16) -> Self {
        return SampleStruct {
            ip_address: address,
            port_number: port,
            sample_socket: Socket::new(
                if address.is_ipv4() { Domain::IPV4 } else { Domain:: IPV6 },
                Type::DGRAM,
                Some(Protocol::UDP)
            ).unwrap()
        }
    }
}

fn main() {
    let foo = SampleStruct::new("127.0.0.1".to_string(), 12345);
    println!("IP address = {}, Port = {}", foo.ip_address.to_string(), foo.port_number);

    let hoo = SampleStruct::new("127.0.0.1", 12345);
    println!("IP address = {}, Port = {}", hoo.ip_address.to_string(), hoo.port_number);

    let priv_ip: IpAddr = "192.168.0.1".parse::<IpAddr>().unwrap();
    let bar = SampleStruct::new(priv_ip, 12345);
    println!("IP address = {}, Port = {}", bar.ip_address.to_string(), bar.port_number);
}
Enter fullscreen mode Exit fullscreen mode

When you run the previous code, you may get the following result.

IP address = 127.0.0.1, Port = 12345
IP address = 127.0.0.1, Port = 12345
IP address = 192.168.0.1, Port = 12345
Enter fullscreen mode Exit fullscreen mode

Link to Rust Playground

Discussion (0)