libuv 2.13.1

A safe rust wrapper for libuv
Documentation
//! Run:
//!
//! ```bash
//! cargo run --example dns
//! ```

extern crate libuv;
use libuv::prelude::*;
use libuv::{AddrInfo, Buf, ConnectReq, GetAddrInfoReq, ReadonlyBuf};
use libuv_sys2::{AF_INET, IPPROTO_TCP, SOCK_STREAM};

fn alloc_buffer(_: Handle, suggested_size: usize) -> Option<Buf> {
    Buf::with_capacity(suggested_size).ok()
}

fn on_read(mut client: StreamHandle, nread: libuv::Result<usize>, mut buf: ReadonlyBuf) {
    match nread {
        Ok(len) => {
            if let Err(e) = client.read_stop() {
                eprintln!("cannot stop read {}", e);
            }

            match buf.to_str(len) {
                Ok(s) => println!("{}", s),
                Err(e) => eprintln!("couldn't convert to string {}", e),
            }
        }
        Err(e) => {
            if e != libuv::Error::EOF {
                eprintln!("Read error {}", e);
            }
            client.close(());
        }
    }

    buf.dealloc();
}

fn on_connect(req: ConnectReq, status: libuv::Result<u32>) {
    match status {
        Ok(_) => {
            if let Err(e) = req.handle().read_start(alloc_buffer, on_read) {
                eprintln!("error starting read {}", e)
            }
        }
        Err(e) => eprintln!("connect failed error {}", e),
    }
}

fn on_resolved(req: GetAddrInfoReq, status: libuv::Result<u32>, res: Vec<AddrInfo>) {
    if let Err(e) = status {
        eprintln!("getaddrinfo callback error {}", e);
        return;
    }

    for info in res {
        if let Some(addr) = info.addr {
            println!("{}", addr);

            let socket = req.r#loop().tcp();
            match socket {
                Ok(mut socket) => {
                    if let Err(e) = socket.connect(&addr, on_connect) {
                        eprintln!("error connecting socket: {}", e);
                    }
                }
                Err(e) => {
                    eprintln!("cannot create socket: {}", e);
                }
            }

            return;
        }
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut r#loop = Loop::default()?;

    let hints = AddrInfo {
        flags: 0,
        family: AF_INET,
        socktype: SOCK_STREAM,
        protocol: IPPROTO_TCP as _,
        canonical_name: None,
        addr: None,
    };
    r#loop.getaddrinfo(
        Some("irc.libera.chat"),
        Some("6667"),
        Some(hints),
        on_resolved,
    )?;

    r#loop.run(RunMode::Default)?;

    Ok(())
}