use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct Msg { pub nonce: u16, pub command: Command, } #[derive(Serialize, Deserialize)] pub enum Command { Hello(String), Goodbye, Update(f32, f32), } impl Msg { pub fn parse(reader: R) -> Option where R: std::io::Read { match serde_json::from_reader(reader) { Ok(r) => Some(r), Err(_err) => None, } } pub fn from_slice(slice: &[u8]) -> Msg { serde_json::from_slice(slice).unwrap() } pub fn emit(&self, writer: W) where W: std::io::Write { serde_json::to_writer(writer, self).unwrap() } } pub struct Connection { nonce: u16, tcp_addr: String, udp_sock: std::net::UdpSocket, } impl Connection { pub fn new(name: &str, host: &str, port: u32) -> Self { let nonce = rand::random(); let tcp_addr = format!("{}:{}", host, port); let stream = std::net::TcpStream::connect(&tcp_addr).unwrap(); Msg { nonce: nonce, command: Command::Hello(name.to_string()), }.emit(stream); let udp_addr = format!("{}:{}", host, port+1); let udp_sock = std::net::UdpSocket::bind("0.0.0.0:9898").unwrap(); udp_sock.connect(udp_addr); Connection { nonce, tcp_addr, udp_sock } } pub fn update(&self, x: f32, y: f32) { let update = Msg { nonce: self.nonce, command: Command::Update(x, y), }; let buf = serde_json::ser::to_vec(&update).unwrap(); self.udp_sock.send(&buf).unwrap(); } pub fn goodbye(&self) { let stream = std::net::TcpStream::connect(&self.tcp_addr).unwrap(); Msg { nonce: self.nonce, command: Command::Goodbye, }.emit(stream); } }