1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! # rich-sdl2-net-rust
//!
//! The SDL_net 2.0 wrapper for Rust.

#![warn(missing_docs)]

use rich_sdl2_rust::Sdl;
use std::{
    ffi::CStr,
    marker::PhantomData,
    mem::MaybeUninit,
    net::{Ipv4Addr, SocketAddrV4},
};

/// Rust FFI to `SDL_net.h`
#[allow(warnings)]
mod bind;
pub mod client;
pub mod conn;
pub mod server;
pub mod sock;

/// A root controller for SDL2_net.
pub struct Net<'sdl> {
    _phantom: PhantomData<&'sdl Sdl>,
}

impl<'sdl> Net<'sdl> {
    /// Constructs a root controller with SDL2 controller.
    pub fn new(_sdl: &'sdl Sdl) -> Self {
        let ret = unsafe { bind::SDLNet_Init() };
        if ret != 0 {
            Sdl::error_then_panic("sdl_net init");
        }
        Self {
            _phantom: PhantomData,
        }
    }

    /// Resolves the ipv4 address to the hostname.
    pub fn resolve_ipv4(&self, addr: Ipv4Addr) -> String {
        let address = bind::IPaddress {
            host: u32::from_ne_bytes(addr.octets()),
            port: 0,
        };
        let cstr = unsafe { CStr::from_ptr(bind::SDLNet_ResolveIP(&address as *const _)) };
        cstr.to_string_lossy().to_string()
    }

    /// Returns all the local addresses of this host's network interfaces.
    pub fn local_addresses(&self) -> Vec<SocketAddrV4> {
        const MAX_ADDRESSES: usize = 16;
        let mut addresses = [MaybeUninit::uninit(); MAX_ADDRESSES];
        let assigned = unsafe {
            bind::SDLNet_GetLocalAddresses(addresses.as_mut_ptr().cast(), MAX_ADDRESSES as _)
        };
        addresses
            .iter()
            .take(assigned as usize)
            .map(|addr| {
                let addr: bind::IPaddress = unsafe { addr.assume_init() };
                SocketAddrV4::new(Ipv4Addr::from(u32::from_be(addr.host)), addr.port)
            })
            .collect()
    }
}

impl Drop for Net<'_> {
    fn drop(&mut self) {
        unsafe { bind::SDLNet_Quit() }
    }
}