use clap::{Parser, Subcommand};
use env_logger::{Builder, Env};
use log::info;
use std::{
net::{Ipv4Addr, SocketAddrV4},
time::Instant,
};
use toe_beans::v4::{Client, ClientConfig, Message, RESOLVED_SERVER_PORT};
#[derive(Parser, Debug)]
#[command(version)]
struct Arguments {
#[command(subcommand)]
command: Commands,
#[command(flatten)]
client_config: ClientConfig,
}
#[derive(Subcommand, Debug)]
enum Commands {
Dora {},
Release {},
Inform {},
Decline {},
}
fn main() {
let now = Instant::now();
Builder::from_env(Env::default().default_filter_or("info")).init();
let args = Arguments::parse();
let config = args.client_config;
let mut client = Client::new(config);
let server_address = SocketAddrV4::new(Ipv4Addr::LOCALHOST, RESOLVED_SERVER_PORT);
match &args.command {
Commands::Dora {} => {
let message = client.discover();
info!("Sending discover message");
client
.socket
.broadcast(&message, RESOLVED_SERVER_PORT)
.unwrap();
info!("Waiting for offer message");
let (offer, _src) = client.socket.receive().unwrap();
info!("Received offer message");
let message = client.request(offer);
info!("Sending request message");
client
.socket
.broadcast(&message, RESOLVED_SERVER_PORT)
.unwrap();
info!("Waiting for ack message");
let (ack, _src) = client.socket.receive::<Message>().unwrap();
info!("Received ack message");
info!("Your ip address: {:?}", ack.yiaddr);
}
Commands::Release {} => {
let message = client.release();
info!("Sending release message");
client.socket.unicast(&message, server_address).unwrap();
}
Commands::Inform {} => {
let message = client.inform(Vec::new());
info!("Sending inform message");
client.socket.unicast(&message, server_address).unwrap();
}
Commands::Decline {} => todo!("Send a decline request"),
}
info!("Completed in {} microseconds", now.elapsed().as_micros());
}