From dec36867d6cd0bf160ee8483578ff1217a584a1c Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Sat, 5 Oct 2024 16:02:20 +0200 Subject: [PATCH] fix: make clippy happy --- flake.lock | 39 +++++++++++++++ src/binary_protocol.rs | 32 +++++------- src/grid.rs | 21 ++++---- src/main.rs | 109 ++++++++++++++++++++++++----------------- src/text_protocol.rs | 59 +++++++++++----------- 5 files changed, 152 insertions(+), 108 deletions(-) diff --git a/flake.lock b/flake.lock index b04907b..61175d0 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,26 @@ { "nodes": { + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1728109939, + "narHash": "sha256-g4kb34YbEbpeLXv6GNONjZtafFkfl9Cd8jTmuYYON8E=", + "owner": "nix-community", + "repo": "fenix", + "rev": "cdfd7bf3e3edaf9e3f6d1e397d3ee601e513613c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1720542800, @@ -18,8 +39,26 @@ }, "root": { "inputs": { + "fenix": "fenix", "nixpkgs": "nixpkgs" } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1728064742, + "narHash": "sha256-tFvUGvqUZjES1yxYT2zEFiTAE0iQKYd+eWKX/6ZqeVw=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "5982d9c420d0dc90739171829f0d2e9c80d98979", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } } }, "root": "root", diff --git a/src/binary_protocol.rs b/src/binary_protocol.rs index 9f18a22..c30a7c1 100644 --- a/src/binary_protocol.rs +++ b/src/binary_protocol.rs @@ -1,27 +1,21 @@ use std::io::{self, Error, ErrorKind}; -use atoi_radix10::parse_from_str; use tokio::io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt}; -use crate::{ - increment_counter, Canvas, Color, Command, Coordinate, Parser, Protocol, Responder, Response, - MEEHHEH, -}; +use crate::{Canvas, Color, Command, IOProtocol, Parser, Responder, Response}; const SIZE_BIN: u8 = 115; const HELP_BIN: u8 = 104; -const LOCK: u8 = 0; const GET_PX_BIN: u8 = 32; const SET_PX_RGB_BIN: u8 = 128; const SET_PX_RGBA_BIN: u8 = 129; const SET_PX_W_BIN: u8 = 130; -const SET_PX_RGB_BIN_LENGTH: usize = 8; pub struct BinaryParser {} impl BinaryParser { pub fn new() -> BinaryParser { - return BinaryParser {}; + BinaryParser {} } } @@ -30,23 +24,23 @@ impl Parser for Binar let fst = reader.read_u8().await; match fst { Ok(i) => match i { - HELP_BIN => return Ok(Command::Help), + HELP_BIN => Ok(Command::Help), SIZE_BIN => { let canvas = reader.read_u8().await?; - return Ok(Command::Size(canvas)); + Ok(Command::Size(canvas)) } GET_PX_BIN => { let canvas = reader.read_u8().await?; let x = reader.read_u16_le().await?; let y = reader.read_u16_le().await?; - return Ok(Command::GetPixel(canvas, x, y)); + Ok(Command::GetPixel(canvas, x, y)) } SET_PX_W_BIN => { let canvas = reader.read_u8().await?; let x = reader.read_u16_le().await?; let y = reader.read_u16_le().await?; let w = reader.read_u8().await?; - return Ok(Command::SetPixel(canvas, x, y, Color::W8(w))); + Ok(Command::SetPixel(canvas, x, y, Color::W8(w))) } SET_PX_RGB_BIN => { let canvas = reader.read_u8().await?; @@ -55,7 +49,7 @@ impl Parser for Binar let r = reader.read_u8().await?; let g = reader.read_u8().await?; let b = reader.read_u8().await?; - return Ok(Command::SetPixel(canvas, x, y, Color::RGB24(r, g, b))); + Ok(Command::SetPixel(canvas, x, y, Color::RGB24(r, g, b))) } SET_PX_RGBA_BIN => { let canvas = reader.read_u8().await?; @@ -65,24 +59,24 @@ impl Parser for Binar let g = reader.read_u8().await?; let b = reader.read_u8().await?; let a = reader.read_u8().await?; - return Ok(Command::SetPixel(canvas, x, y, Color::RGBA32(r, g, b, a))); + Ok(Command::SetPixel(canvas, x, y, Color::RGBA32(r, g, b, a))) } _ => { eprintln!("received illegal command: {}", i); - return Err(Error::from(ErrorKind::InvalidInput)); + Err(Error::from(ErrorKind::InvalidInput)) } }, Err(err) => { eprintln!("{}", err); - return Err(err); + Err(err) } } } } -impl MEEHHEH for BinaryParser { +impl IOProtocol for BinaryParser { fn change_canvas(&mut self, _canvas: Canvas) -> io::Result<()> { - return Err(Error::from(ErrorKind::Unsupported)); + Err(Error::from(ErrorKind::Unsupported)) } } @@ -111,9 +105,7 @@ To set a pixel using RGB, use ({:02X}) (u8 canvas) (x as u16_le) (y as u16_le) ( #[cfg(test)] mod tests { use super::*; - use crate::grid::FlutGrid; use tokio::io::BufReader; - use tokio_test::assert_ok; #[tokio::test] async fn test_bin_help_parse() { diff --git a/src/grid.rs b/src/grid.rs index 5580f7f..aa25db5 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -1,9 +1,10 @@ use std::cell::SyncUnsafeCell; -use crate::{Coordinate, Response}; +use crate::Coordinate; pub trait Grid { fn get(&self, x: I, y: I) -> Option<&V>; + #[allow(dead_code)] fn get_unchecked(&self, x: I, y: I) -> &V; fn set(&self, x: I, y: I, value: V); } @@ -20,15 +21,15 @@ impl FlutGrid { for _ in 0..(size_x * size_y) { vec.push(value.clone()); } - return FlutGrid { + FlutGrid { size_x, size_y, cells: vec.into(), - }; + } } pub fn get_size(&self) -> (usize, usize) { - return (self.size_x, self.size_y); + (self.size_x, self.size_y) } } @@ -39,16 +40,14 @@ impl FlutGrid { if x >= self.size_x || y >= self.size_y { return None; } - return Some((y * self.size_x) + x); + Some((y * self.size_x) + x) } } impl Grid for FlutGrid { fn get(&self, x: Coordinate, y: Coordinate) -> Option<&T> { - match self.index(x, y) { - None => None, - Some(idx) => Some(unsafe { &(*self.cells.get())[idx] }), - } + self.index(x, y) + .map(|idx| unsafe { &(*self.cells.get())[idx] }) } fn set(&self, x: Coordinate, y: Coordinate, value: T) { @@ -60,7 +59,7 @@ impl Grid for FlutGrid { fn get_unchecked(&self, x: Coordinate, y: Coordinate) -> &T { let idx = y as usize * self.size_x + x as usize; - return unsafe { &(*self.cells.get())[idx] }; + unsafe { &(*self.cells.get())[idx] } } } @@ -127,7 +126,7 @@ mod tests { b.iter(|| { let x = test::black_box(293); let y = test::black_box(222); - let color = test::black_box(293923); + let color = test::black_box(293_923); grid.set(x, y, color); }) } diff --git a/src/main.rs b/src/main.rs index 2b4082e..ce662fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,9 +6,7 @@ mod grid; mod text_protocol; use std::{ - cell::SyncUnsafeCell, io::{self, Error, ErrorKind}, - iter::once, sync::{atomic::AtomicU64, Arc}, time::Duration, }; @@ -17,11 +15,13 @@ use binary_protocol::BinaryParser; use grid::{FlutGrid, Grid}; use text_protocol::TextParser; use tokio::{ - io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, + io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, net::TcpListener, }; extern crate test; +const GRID_LENGTH: usize = 1; +const HOST: &str = "0.0.0.0:7791"; const HELP_TEXT: &[u8] = b"Flurry is a pixelflut implementation, this means you can use commands to get and set pixels in the canvas SIZE returns the size of the canvas @@ -31,7 +31,6 @@ PX {x} {y} {RGB} sets the color of the pixel at {x}, {y} to the rgb value PX {x} {y} {RGBA} blends the pixel at {x}, {y} with the rgb value weighted by the a PX {x} {y} {W} sets the color of the pixel at {x}, {y} to the grayscale value "; -const GRID_LENGTH: usize = 1; static COUNTER: AtomicU64 = AtomicU64::new(0); @@ -45,9 +44,8 @@ fn set_pixel_rgba( y: Coordinate, rgb: u32, ) { - match grids.get(canvas as usize) { - Some(grid) => grid.set(x, y, rgb), - None => (), + if let Some(grid) = grids.get(canvas as usize) { + grid.set(x, y, rgb) } } @@ -58,8 +56,8 @@ fn get_pixel( y: Coordinate, ) -> Option<&u32> { match grids.get(canvas as usize) { - Some(grid) => return grid.get(x, y), - None => return None, + Some(grid) => grid.get(x, y), + None => None, } } @@ -105,7 +103,7 @@ where async fn parse(&self, reader: &mut R) -> io::Result; } -trait MEEHHEH { +trait IOProtocol { fn change_canvas(&mut self, canvas: Canvas) -> io::Result<()>; } @@ -116,12 +114,12 @@ where async fn unparse(&self, response: Response, writer: &mut W) -> io::Result<()>; } -async fn listen_handle() { +async fn listen_handle() -> io::Result<()> { let mut interval = tokio::time::interval(Duration::from_millis(1000)); loop { interval.tick().await; let cnt = COUNTER.load(std::sync::atomic::Ordering::Relaxed); - println!("{} pixels were changed", cnt); + println!("{cnt} pixels were changed"); } } @@ -170,15 +168,16 @@ where match_parser!(parser: self.parser => parser.unparse(Response::Help, &mut self.writer).await?); self.writer.flush().await?; - return Ok(()); + Ok(()) } async fn size_command(&mut self, canvas: Canvas) -> io::Result<()> { let (x, y) = self.grids[canvas as usize].get_size(); - match_parser!(parser: self.parser => parser.unparse(Response::Size(x as Coordinate, y as Coordinate), &mut self.writer).await?); + match_parser!(parser: self.parser => parser.unparse( + Response::Size(Coordinate::try_from(x).unwrap(), Coordinate::try_from(y).unwrap()), &mut self.writer).await?); self.writer.flush().await?; - return Ok(()); + Ok(()) } async fn get_pixel_command( @@ -194,10 +193,10 @@ where match_parser!(parser: self.parser => parser.unparse(Response::GetPixel(x,y,[color[0], color[1], color[2]]), &mut self.writer).await?); self.writer.flush().await?; - return Ok(()); + Ok(()) } - async fn set_pixel_command( + fn set_pixel_command( &mut self, canvas: Canvas, x: Coordinate, @@ -211,28 +210,28 @@ where }; set_pixel_rgba(self.grids.as_ref(), canvas, x, y, c); increment_counter(); - return Ok(()); + Ok(()) } - async fn change_canvas_command(&mut self, canvas: Canvas) -> io::Result<()> { + fn change_canvas_command(&mut self, canvas: Canvas) -> io::Result<()> { match_parser!(parser: self.parser => parser.change_canvas(canvas)) } - async fn change_protocol(&mut self, protocol: Protocol) -> io::Result<()> { + fn change_protocol(&mut self, protocol: Protocol) -> io::Result<()> { match protocol { Protocol::Text => self.parser = ParserTypes::TextParser(TextParser::new(0)), Protocol::Binary => self.parser = ParserTypes::BinaryParser(BinaryParser::new()), } - return Ok(()); + Ok(()) } pub fn new(reader: R, writer: W, grids: Arc<[grid::FlutGrid]>) -> FlutClient { - return FlutClient { + FlutClient { reader: BufReader::new(reader), writer: BufWriter::new(writer), grids, parser: ParserTypes::TextParser(TextParser::new(0)), - }; + } } pub async fn process_socket(&mut self) -> io::Result<()> { @@ -247,10 +246,10 @@ where Ok(Command::Size(canvas)) => self.size_command(canvas).await?, Ok(Command::GetPixel(canvas, x, y)) => self.get_pixel_command(canvas, x, y).await?, Ok(Command::SetPixel(canvas, x, y, color)) => { - self.set_pixel_command(canvas, x, y, color).await? + self.set_pixel_command(canvas, x, y, color)?; } - Ok(Command::ChangeCanvas(canvas)) => self.change_canvas_command(canvas).await?, - Ok(Command::ChangeProtocol(protocol)) => self.change_protocol(protocol).await?, + Ok(Command::ChangeCanvas(canvas)) => self.change_canvas_command(canvas)?, + Ok(Command::ChangeProtocol(protocol)) => self.change_protocol(protocol)?, Err(err) if err.kind() == ErrorKind::UnexpectedEof => { return Ok(()); @@ -263,35 +262,53 @@ where } } -#[tokio::main] -async fn main() -> io::Result<()> { - println!("created grids"); - let grids: Arc<[FlutGrid; GRID_LENGTH]> = - [grid::FlutGrid::init(800, 600, 0xff00ffff)].into(); - - let flut_listener = TcpListener::bind("0.0.0.0:7791").await?; - println!("bound flut listener"); - - let _ = tokio::spawn(listen_handle()); - +async fn handle_flut( + flut_listener: TcpListener, + grids: Arc<[grid::FlutGrid]>, +) -> io::Result<()> { + let mut handles = Vec::new(); loop { let (mut socket, _) = flut_listener.accept().await?; let grids = grids.clone(); - let _ = tokio::spawn(async move { + handles.push(tokio::spawn(async move { let (reader, writer) = socket.split(); let mut connection = FlutClient::new(reader, writer, grids); let resp = connection.process_socket().await; match resp { - Ok(()) => return Ok(()), - Err(err) => return Err(err), + Ok(()) => Ok(()), + Err(err) => Err(err), } - }); + })); + } +} + +#[tokio::main] +#[allow(clippy::needless_return)] +async fn main() { + println!("created grids"); + let grids: Arc<[FlutGrid; GRID_LENGTH]> = + [grid::FlutGrid::init(800, 600, 0xff00ffff)].into(); + + let flut_listener = match TcpListener::bind(HOST).await { + Ok(listener) => listener, + Err(_) => { + eprintln!("Was unable to bind to {HOST}, please check if a different process is bound"); + return; + } + }; + println!("bound flut listener"); + + let handles = vec![ + // log the amount of changed pixels each second + (tokio::spawn(listen_handle())), + // accept and handle flut connections + (tokio::spawn(handle_flut(flut_listener, grids))), + ]; + + for handle in handles { + println!("joined handle had result {:?}", handle.await) } } #[cfg(test)] -mod tests { - use super::*; - use crate::grid::FlutGrid; - use tokio_test::assert_ok; -} +mod tests {} diff --git a/src/text_protocol.rs b/src/text_protocol.rs index 2625395..a2766c0 100644 --- a/src/text_protocol.rs +++ b/src/text_protocol.rs @@ -4,18 +4,19 @@ use atoi_radix10::parse_from_str; use tokio::io::{AsyncBufRead, AsyncBufReadExt, AsyncWriteExt}; use crate::{ - Canvas, Color, Command, Coordinate, Parser, Protocol, Responder, Response, GRID_LENGTH, - HELP_TEXT, MEEHHEH, + Canvas, Color, Command, Coordinate, IOProtocol, Parser, Protocol, Responder, Response, + GRID_LENGTH, HELP_TEXT, }; pub struct TextParser { canvas: Canvas, } +#[allow(dead_code)] fn parse_coordinate(string: &str) -> io::Result { match parse_from_str(string) { - Ok(coord) => return Ok(coord), - Err(_) => return Err(Error::from(ErrorKind::InvalidInput)), + Ok(coord) => Ok(coord), + Err(_) => Err(Error::from(ErrorKind::InvalidInput)), } } @@ -28,12 +29,12 @@ fn parse_color(color: &str) -> io::Result { _ => return Err(Error::from(ErrorKind::InvalidInput)), } } - return Err(Error::from(ErrorKind::InvalidInput)); + Err(Error::from(ErrorKind::InvalidInput)) } impl TextParser { pub fn new(canvas: Canvas) -> TextParser { - return TextParser { canvas }; + TextParser { canvas } } fn parse_pixel(&self, line: &str) -> io::Result { @@ -44,16 +45,14 @@ impl TextParser { let y_coordinate = split.next().ok_or(Error::from(ErrorKind::InvalidInput))?; if let (Ok(horizontal), Ok(vertical)) = (x_coordinate.parse(), y_coordinate.parse()) { match split.next() { - None => return Ok(Command::GetPixel(self.canvas, horizontal, vertical)), + None => Ok(Command::GetPixel(self.canvas, horizontal, vertical)), Some(color) => match parse_color(color) { - Ok(color) => { - return Ok(Command::SetPixel(self.canvas, horizontal, vertical, color)) - } - Err(err) => return Err(err), + Ok(color) => Ok(Command::SetPixel(self.canvas, horizontal, vertical, color)), + Err(err) => Err(err), }, } } else { - return Err(Error::from(ErrorKind::InvalidInput)); + Err(Error::from(ErrorKind::InvalidInput)) } } fn parse_canvas(&self, line: &str) -> io::Result { @@ -62,9 +61,9 @@ impl TextParser { let _command = split.next().ok_or(Error::from(ErrorKind::InvalidInput))?; let canvas = split.next().ok_or(Error::from(ErrorKind::InvalidInput))?; if let Ok(canvas) = canvas.parse() { - return Ok(Command::ChangeCanvas(canvas)); + Ok(Command::ChangeCanvas(canvas)) } else { - return Err(Error::from(ErrorKind::InvalidInput)); + Err(Error::from(ErrorKind::InvalidInput)) } } fn parse_protocol(&self, line: &str) -> io::Result { @@ -73,9 +72,9 @@ impl TextParser { let _command = split.next().ok_or(Error::from(ErrorKind::InvalidInput))?; let protocol = split.next().ok_or(Error::from(ErrorKind::InvalidInput))?; match protocol { - "binary" => return Ok(Command::ChangeProtocol(Protocol::Binary)), - "text" => return Ok(Command::ChangeProtocol(Protocol::Text)), - _ => return Err(Error::from(ErrorKind::InvalidInput)), + "binary" => Ok(Command::ChangeProtocol(Protocol::Binary)), + "text" => Ok(Command::ChangeProtocol(Protocol::Text)), + _ => Err(Error::from(ErrorKind::InvalidInput)), } } } @@ -83,7 +82,7 @@ impl TextParser { impl Parser for TextParser { async fn parse(&self, reader: &mut R) -> io::Result { let mut line = "".to_string(); - if let Ok(_) = reader.read_line(&mut line).await { + if reader.read_line(&mut line).await.is_ok() { if line.starts_with("HELP") { return Ok(Command::Help); } else if line.starts_with("SIZE") { @@ -96,17 +95,17 @@ impl Parser for TextP return self.parse_protocol(&line); } } - return Err(Error::from(ErrorKind::InvalidInput)); + Err(Error::from(ErrorKind::InvalidInput)) } } -impl MEEHHEH for TextParser { +impl IOProtocol for TextParser { fn change_canvas(&mut self, canvas: Canvas) -> io::Result<()> { if (canvas as usize) < GRID_LENGTH { self.canvas = canvas; - return Ok(()); + Ok(()) } else { - return Err(Error::from(ErrorKind::InvalidInput)); + Err(Error::from(ErrorKind::InvalidInput)) } } } @@ -132,9 +131,7 @@ impl Responder for TextParser { #[cfg(test)] mod tests { use super::*; - use crate::grid::FlutGrid; use tokio::io::BufReader; - use tokio_test::assert_ok; #[tokio::test] async fn test_help_parse() { @@ -142,7 +139,7 @@ mod tests { let reader = tokio_test::io::Builder::new().read(b"HELP\n").build(); let mut bufreader = BufReader::new(reader); let thingy = parser.parse(&mut bufreader).await; - assert_eq!(thingy.unwrap(), Command::Help) + assert_eq!(thingy.unwrap(), Command::Help); } #[tokio::test] @@ -151,7 +148,7 @@ mod tests { let reader = tokio_test::io::Builder::new().read(b"SIZE\n").build(); let mut bufreader = BufReader::new(reader); let thingy = parser.parse(&mut bufreader).await; - assert_eq!(thingy.unwrap(), Command::Size(0)) + assert_eq!(thingy.unwrap(), Command::Size(0)); } #[tokio::test] @@ -160,7 +157,7 @@ mod tests { let reader = tokio_test::io::Builder::new().read(b"CANVAS 12\n").build(); let mut bufreader = BufReader::new(reader); let thingy = parser.parse(&mut bufreader).await; - assert_eq!(thingy.unwrap(), Command::ChangeCanvas(12)) + assert_eq!(thingy.unwrap(), Command::ChangeCanvas(12)); } #[tokio::test] @@ -174,7 +171,7 @@ mod tests { assert_eq!( thingy.unwrap(), Command::SetPixel(0, 28283, 29991, Color::W8(0x81)) - ) + ); } #[tokio::test] @@ -188,7 +185,7 @@ mod tests { assert_eq!( thingy.unwrap(), Command::SetPixel(0, 28283, 29991, Color::RGB24(0x88, 0x00, 0xff)) - ) + ); } #[tokio::test] @@ -202,7 +199,7 @@ mod tests { assert_eq!( thingy.unwrap(), Command::SetPixel(0, 28283, 29991, Color::RGBA32(0x88, 0x00, 0xff, 0x28)) - ) + ); } #[tokio::test] @@ -213,7 +210,7 @@ mod tests { .build(); let mut bufreader = BufReader::new(reader); let thingy = parser.parse(&mut bufreader).await; - assert_eq!(thingy.unwrap(), Command::GetPixel(0, 28283, 29991)) + assert_eq!(thingy.unwrap(), Command::GetPixel(0, 28283, 29991)); } #[tokio::test]