rustun 0.5.0

A library for implementing STUN server and client asynchronously
Documentation
#[macro_use]
extern crate trackable;

use clap::Parser;
use fibers_transport::UdpTransporter;
use futures::Future;
use rustun::channel::Channel;
use rustun::client::Client;
use rustun::message::Request;
use rustun::transport::StunUdpTransporter;
use rustun::Error;
use std::net::ToSocketAddrs;
use stun_codec::rfc5389;
use stun_codec::{MessageDecoder, MessageEncoder};
use trackable::error::Failed;
use trackable::error::MainError;

#[derive(Debug, Parser)]
struct Args {
    host: String,

    #[clap(short, long, default_value_t = 3478)]
    port: usize,
}

fn main() -> Result<(), MainError> {
    let args = Args::parse();
    let peer_addr = track_assert_some!(
        track_any_err!(format!("{}:{}", args.host, args.port).to_socket_addrs())?
            .filter(|x| x.is_ipv4())
            .nth(0),
        Failed
    );

    let local_addr = "0.0.0.0:0".parse().unwrap();
    let response = UdpTransporter::<MessageEncoder<_>, MessageDecoder<_>>::bind(local_addr)
        .map_err(Error::from)
        .map(StunUdpTransporter::new)
        .map(Channel::new)
        .and_then(move |channel| {
            let client = Client::new(&fibers_global::handle(), channel);
            let request = Request::<rfc5389::Attribute>::new(rfc5389::methods::BINDING);
            client.call(peer_addr, request)
        });
    let response = track!(fibers_global::execute(response))?;
    println!("{:?}", response);
    Ok(())
}