This commit is contained in:
Theis Pieter Hollebeek 2026-03-30 10:00:30 +02:00
parent 45f9f1ee78
commit 0e32e57d7d

View File

@ -1,72 +1,47 @@
use std::{ use std::{
io::{Read, Write}, io::{BufRead, BufReader},
net::TcpStream, net::TcpStream,
}; };
struct Server; struct Server(TcpStream);
struct UnregisteredServer(TcpStream);
struct RegisteredServer(TcpStream);
impl Server {
pub fn bind(addr: &str) -> UnregisteredServer {
UnregisteredServer(TcpStream::connect(addr).unwrap())
}
}
impl UnregisteredServer {
pub fn register(mut self, id: u64) -> Result<RegisteredServer, UnregisteredServer> {
self.0.write(b"register ").unwrap();
self.0.write(id.to_string().as_bytes()).unwrap();
self.0.write(b"\n").unwrap();
let mut buf: [u8; 2] = [0, 0];
self.0.read(&mut buf).unwrap();
match &buf {
b"OK" => Ok(RegisteredServer(self.0)),
b"NO" => Err(self),
_ => panic!("server error"),
}
}
}
struct Data { struct Data {
sway: f64, x: f64,
y: f64,
z: f64,
a: f64,
b: f64,
c: f64,
} }
struct Pump<'a>(&'a mut TcpStream, [u8; 4], usize); impl Server {
pub fn bind(addr: &str) -> Server {
Server(TcpStream::connect(addr).unwrap())
}
fn get_fallible(data: &[f64], idx: usize) -> Result<f64, String> {
data.get(idx)
.map(|idx| *idx)
.ok_or_else(|| format!("protocol error: {idx}"))
}
pub fn read(&mut self) -> Result<Data, String> {
let mut reader = BufReader::new(&mut self.0);
let mut data = String::new();
reader
.read_line(&mut data)
.map_err(|err| format!("io error: {}", err.to_string()))?;
let data = data
.split(",")
.map(|x| x.parse::<f64>())
.collect::<Result<Vec<f64>, _>>();
let data = data.map_err(|err| format!("protocol error: {}", err.to_string()))?;
impl<'a> Pump<'a> { Ok(Data {
pub fn new(stream: &'a mut TcpStream) -> Self { x: Self::get_fallible(&data, 0)?,
Self(stream, [0, 0, 0, 0], 0) y: Self::get_fallible(&data, 1)?,
} z: Self::get_fallible(&data, 2)?,
} a: Self::get_fallible(&data, 3)?,
b: Self::get_fallible(&data, 4)?,
impl<'a> Iterator for Pump<'a> { c: Self::get_fallible(&data, 5)?,
type Item = std::io::Result<Data>; })
fn next(&mut self) -> Option<Self::Item> {
loop {
let mut bytes = self.0.bytes();
let Some(byte) = bytes.next() else {
break None;
};
let byte = match byte {
Ok(byte) => byte,
Err(err) => break Some(Err(err)),
};
self.1[self.2] = byte;
self.2 += 1;
if self.2 == 4 {
let sway = u32::from_le_bytes(self.1) as f64;
let sway = (sway - 64_000_000.0) / 2.0;
break Some(Ok(Data { sway }));
}
}
}
}
impl RegisteredServer {
fn pump(&mut self) -> Pump<'_> {
Pump::new(&mut self.0)
} }
} }