udp_polygon 0.1.0

A UDP datagram library for Rust
Documentation
use std::net::{IpAddr, SocketAddr, UdpSocket};
pub mod config;
use config::Config;
use std::sync::mpsc::{self, Receiver, Sender};
use tokio;

#[derive(Debug)]
pub struct Polygon {
    pub socket: UdpSocket,
    pub buffer: [u8; 65535],
    pub destination: Option<SocketAddr>,
}

impl Polygon {
    pub fn get_channel() -> (Sender<String>, Receiver<String>) {
        let (tx, rx) = mpsc::channel();
        (tx, rx)
    }
    pub fn configure(config: Config) -> Self {
        let addrs = config
            .bind_addresses
            .to_vec()
            .into_iter()
            .map(|addr| match addr.ip {
                IpAddr::V4(ipv4) => SocketAddr::new(IpAddr::V4(ipv4), addr.port),
                IpAddr::V6(ipv6) => SocketAddr::new(IpAddr::V6(ipv6), addr.port),
            })
            .collect::<Vec<_>>();

        let socket = UdpSocket::bind(&addrs[..]).unwrap();
        let buffer = [0_u8; 65535];
        Self {
            socket,
            buffer,
            destination: if let Some(addr) = config.destination_address {
                match addr.ip {
                    IpAddr::V4(ipv4) => Some(SocketAddr::new(IpAddr::V4(ipv4), addr.port)),
                    IpAddr::V6(ipv6) => Some(SocketAddr::new(IpAddr::V6(ipv6), addr.port)),
                }
            } else {
                None
            },
        }
    }
    pub fn receive(&mut self) -> Receiver<String> {
        let mut socket = self.socket.try_clone().unwrap();
        let mut buffer = self.buffer.clone();
        let (tx, rx) = Polygon::get_channel();
        tokio::spawn(async move {
            loop {
                let maybe: Option<String>;
                {
                    let packets_queued = peek(&mut socket, &mut buffer);
                    if packets_queued > 0 {
                        maybe = match read(&mut socket, &mut buffer) {
                            Ok(buf) => Some(buf),
                            Err(_) => None,
                        };

                        if let Some(data) = maybe {
                            tx.send(data).unwrap();
                        }
                    }
                }
            }
        });

        rx
    }
    pub fn send(&mut self, data: String) {
        let destination = self.destination.clone().unwrap();
        self.socket
            .send_to(
                data.as_bytes(),
                format!("{}:{}", &destination.ip(), &destination.port()),
            )
            .unwrap();
    }
}

fn peek(socket: &mut UdpSocket, buffer: &mut [u8; 65535]) -> usize {
    match socket.peek(buffer) {
        Ok(received) => received,
        Err(_e) => 0,
    }
}

fn read(socket: &mut UdpSocket, buffer: &mut [u8; 65535]) -> Result<String, String> {
    let (amt, _src) = socket.recv_from(buffer).unwrap();
    let slice = &mut buffer[..amt];
    slice.to_vec();
    let message = String::from_utf8_lossy(slice);
    Ok(message.to_string())
}