From 92ae8586e2f8c7661476b20454980897a5727b70 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Tue, 10 Dec 2024 23:38:23 +0100 Subject: [PATCH 01/13] add `Clone` and `to_bytes()` to Color as utilities --- src/color.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/color.rs b/src/color.rs index b372a72..2341176 100644 --- a/src/color.rs +++ b/src/color.rs @@ -2,13 +2,23 @@ use std::fmt::Display; use rand::{distributions::Standard, prelude::Distribution}; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub enum Color { RGB24(u8, u8, u8), RGBA32(u8, u8, u8, u8), W8(u8), } +impl Color { + pub fn to_bytes(&self) -> [u8; 4] { + match self { + Color::RGB24(r, g, b) => [*r, *g, *b, 0xff], + Color::RGBA32(r, g, b, a) => [*r, *g, *b, *a], + Color::W8(w) => [*w, *w, *w, 0xff], + } + } +} + impl Display for Color { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { From fb7e9310aed8d5d262db8d4c28cc1beb6b2d81df Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Tue, 10 Dec 2024 23:40:50 +0100 Subject: [PATCH 02/13] add the palette protocol, with up to 256 colors in the palette --- Cargo.toml | 1 + src/flutclient.rs | 12 +++- src/lib.rs | 1 + src/protocols.rs | 2 + src/protocols/palette_protocol.rs | 105 ++++++++++++++++++++++++++++++ src/protocols/text_protocol.rs | 1 + 6 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 src/protocols/palette_protocol.rs diff --git a/Cargo.toml b/Cargo.toml index 7f87449..3670c11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } default = ["text", "binary"] text = [] binary = [] +palette = [] [dev-dependencies] tempfile = "*" diff --git a/src/flutclient.rs b/src/flutclient.rs index ddd9f2f..9fbc31c 100644 --- a/src/flutclient.rs +++ b/src/flutclient.rs @@ -9,7 +9,7 @@ use crate::{ get_pixel, grid::{self, Flut}, increment_counter, - protocols::{BinaryParser, IOProtocol, Parser, Responder, TextParser}, + protocols::{BinaryParser, IOProtocol, PaletteParser, Parser, Responder, TextParser}, set_pixel_rgba, Canvas, Color, Command, Coordinate, Protocol, Response, }; @@ -26,10 +26,10 @@ macro_rules! build_parser_type_enum { impl std::default::Default for ParserTypes { // add code here + #[allow(unreachable_code)] fn default() -> Self { $( #[cfg(feature = $feat)] - #[allow(unreachable_code)] return ParserTypes::$name(<$t>::default()); )* } @@ -62,6 +62,7 @@ macro_rules! build_parser_type_enum { build_parser_type_enum! { TextParser: TextParser: "text", BinaryParser: BinaryParser: "binary", + PaletteParser: PaletteParser: "palette", } pub struct FlutClient @@ -145,6 +146,13 @@ where self.writer.write(b"feature \"binary\" is not enabled."); self.writer.flush(); } + #[cfg(feature = "palette")] + Protocol::Palette => self.parser = ParserTypes::Palette(PaletteParser::default()), + #[cfg(not(feature = "palette"))] + Protocol::Palette => { + self.writer.write(b"feature \"binary\" is not enabled."); + self.writer.flush(); + } } } diff --git a/src/lib.rs b/src/lib.rs index 4b35c6f..28ffa76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,6 +57,7 @@ fn increment_counter(amount: u64) { pub enum Protocol { Text, Binary, + Palette, } #[derive(Debug, PartialEq)] diff --git a/src/protocols.rs b/src/protocols.rs index 12aa1a6..5fe8c4c 100644 --- a/src/protocols.rs +++ b/src/protocols.rs @@ -1,9 +1,11 @@ mod binary_protocol; +mod palette_protocol; mod text_protocol; use std::io; pub use binary_protocol::BinaryParser; +pub use palette_protocol::PaletteParser; pub use text_protocol::TextParser; use tokio::io::AsyncWriteExt; diff --git a/src/protocols/palette_protocol.rs b/src/protocols/palette_protocol.rs new file mode 100644 index 0000000..c053597 --- /dev/null +++ b/src/protocols/palette_protocol.rs @@ -0,0 +1,105 @@ +use std::io::{self, Error, ErrorKind}; + +use image::EncodableLayout; +use tokio::io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt}; + +use crate::{Canvas, Color, Command, Response}; + +use super::{IOProtocol, Parser, Responder}; + +const SIZE_BIN: u8 = 115; +const HELP_BIN: u8 = 104; +const GET_PX_BIN: u8 = 32; +const SET_PX_BIN: u8 = 33; + +#[derive(Clone)] +pub struct PaletteParser { + colors: [Color; 256], +} + +impl Default for PaletteParser { + fn default() -> Self { + PaletteParser { + colors: [const { Color::RGB24(0, 0, 0) }; 256], + } + } +} + +impl Parser for PaletteParser { + async fn parse(&self, reader: &mut R) -> io::Result { + let fst = reader.read_u8().await; + match fst { + Ok(command) => match command { + HELP_BIN => Ok(Command::Help), + SIZE_BIN => { + let canvas = reader.read_u8().await?; + Ok(Command::Size(canvas)) + } + GET_PX_BIN => { + let canvas = reader.read_u8().await?; + let horizontal = reader.read_u16().await?; + let vertical = reader.read_u16().await?; + Ok(Command::GetPixel(canvas, horizontal, vertical)) + } + SET_PX_BIN => { + let canvas = reader.read_u8().await?; + let horizontal = reader.read_u16().await?; + let vertical = reader.read_u16().await?; + let color = reader.read_u8().await?; + Ok(Command::SetPixel(canvas, horizontal, vertical, unsafe { + self.colors.get_unchecked(color as usize).clone() + })) + } + _ => { + tracing::error!("received illegal command: {command}"); + Err(Error::from(ErrorKind::InvalidInput)) + } + }, + Err(err) => { + tracing::error!("{err}"); + Err(err) + } + } + } +} + +impl IOProtocol for PaletteParser { + fn change_canvas(&mut self, _canvas: Canvas) -> io::Result<()> { + Err(Error::from(ErrorKind::Unsupported)) + } +} + +impl Responder for PaletteParser { + async fn unparse(&self, response: Response, writer: &mut W) -> io::Result<()> { + match response { + Response::Help => { + writer + .write_all( + self.colors + .iter() + .map(|c| c.to_bytes()) + .collect::>() + .concat() + .as_bytes(), + ) + .await + } + Response::Size(x, y) => { + writer.write_u16(x).await?; + writer.write_u16(y).await + } + Response::GetPixel(_, _, c) => { + writer.write_u8(c[0]).await?; + writer.write_u8(c[1]).await?; + writer.write_u8(c[2]).await + } + } + } +} + +#[cfg(test)] +#[allow(clippy::needless_return)] +mod tests { + use super::*; + use tokio::io::BufReader; +} diff --git a/src/protocols/text_protocol.rs b/src/protocols/text_protocol.rs index 1c711a2..cebf21f 100644 --- a/src/protocols/text_protocol.rs +++ b/src/protocols/text_protocol.rs @@ -106,6 +106,7 @@ impl TextParser { match protocol { "binary" => Ok(Command::ChangeProtocol(Protocol::Binary)), "text" => Ok(Command::ChangeProtocol(Protocol::Text)), + "palette" => Ok(Command::ChangeProtocol(Protocol::Palette)), _ => Err(Error::from(ErrorKind::InvalidInput)), } } From 95a408910ca99b4f70a755bc3b5f71de5d6535d2 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 11:47:41 +0100 Subject: [PATCH 03/13] feature flags for use statements --- src/flutclient.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/flutclient.rs b/src/flutclient.rs index 9fbc31c..a905a29 100644 --- a/src/flutclient.rs +++ b/src/flutclient.rs @@ -5,11 +5,17 @@ use std::{ use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}; +#[cfg(feature = "binary")] +use crate::protocols::BinaryParser; +#[cfg(feature = "palette")] +use crate::protocols::PaletteParser; +#[cfg(feature = "text")] +use crate::protocols::TextParser; use crate::{ get_pixel, grid::{self, Flut}, increment_counter, - protocols::{BinaryParser, IOProtocol, PaletteParser, Parser, Responder, TextParser}, + protocols::{IOProtocol, Parser, Responder}, set_pixel_rgba, Canvas, Color, Command, Coordinate, Protocol, Response, }; From 676dc184140df658e4f3fdfc538a109d549294d2 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 11:47:55 +0100 Subject: [PATCH 04/13] make the writes and flush await --- src/flutclient.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/flutclient.rs b/src/flutclient.rs index a905a29..8c222a9 100644 --- a/src/flutclient.rs +++ b/src/flutclient.rs @@ -136,30 +136,37 @@ where match_parser!(parser: self.parser => parser.change_canvas(canvas)) } - fn change_protocol(&mut self, protocol: &Protocol) { + async fn change_protocol(&mut self, protocol: &Protocol) -> io::Result<()> { match protocol { #[cfg(feature = "text")] Protocol::Text => self.parser = ParserTypes::TextParser(TextParser::default()), #[cfg(not(feature = "text"))] Protocol::Text => { - self.writer.write(b"feature \"text\" is not enabled."); - self.writer.flush(); + self.writer + .write_all(b"feature \"text\" is not enabled.") + .await?; + self.writer.flush().await?; } #[cfg(feature = "binary")] Protocol::Binary => self.parser = ParserTypes::BinaryParser(BinaryParser::default()), #[cfg(not(feature = "binary"))] Protocol::Binary => { - self.writer.write(b"feature \"binary\" is not enabled."); - self.writer.flush(); + self.writer + .write_all(b"feature \"binary\" is not enabled.") + .await?; + self.writer.flush().await?; } #[cfg(feature = "palette")] - Protocol::Palette => self.parser = ParserTypes::Palette(PaletteParser::default()), + Protocol::Palette => self.parser = ParserTypes::PaletteParser(PaletteParser::default()), #[cfg(not(feature = "palette"))] Protocol::Palette => { - self.writer.write(b"feature \"binary\" is not enabled."); - self.writer.flush(); + self.writer + .write_all(b"feature \"binary\" is not enabled.") + .await?; + self.writer.flush().await?; } } + Ok(()) } pub fn new(reader: R, writer: W, grids: Arc<[grid::Flut]>) -> Self { @@ -187,7 +194,7 @@ where break 'outer; } Ok(Command::ChangeProtocol(protocol)) => { - self.change_protocol(&protocol); + self.change_protocol(&protocol).await?; break 'outer; } Err(err) if err.kind() == ErrorKind::UnexpectedEof => { From 2cde50964d4321461dbb913b6b4c41a830904637 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 11:48:45 +0100 Subject: [PATCH 05/13] initialize with random palette --- src/protocols/palette_protocol.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/protocols/palette_protocol.rs b/src/protocols/palette_protocol.rs index c053597..7c42b27 100644 --- a/src/protocols/palette_protocol.rs +++ b/src/protocols/palette_protocol.rs @@ -1,6 +1,7 @@ use std::io::{self, Error, ErrorKind}; use image::EncodableLayout; +use rand::random; use tokio::io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt}; use crate::{Canvas, Color, Command, Response}; @@ -20,7 +21,7 @@ pub struct PaletteParser { impl Default for PaletteParser { fn default() -> Self { PaletteParser { - colors: [const { Color::RGB24(0, 0, 0) }; 256], + colors: [0; 256].map(|_| random()), } } } From ee86585d77a3c02c49b4ca3e2561a125e9f5a6ba Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 11:49:02 +0100 Subject: [PATCH 06/13] rename constant to be more descriptive --- src/protocols/palette_protocol.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/protocols/palette_protocol.rs b/src/protocols/palette_protocol.rs index 7c42b27..b122f35 100644 --- a/src/protocols/palette_protocol.rs +++ b/src/protocols/palette_protocol.rs @@ -11,7 +11,7 @@ use super::{IOProtocol, Parser, Responder}; const SIZE_BIN: u8 = 115; const HELP_BIN: u8 = 104; const GET_PX_BIN: u8 = 32; -const SET_PX_BIN: u8 = 33; +const SET_PX_PALETTE_BIN: u8 = 33; #[derive(Clone)] pub struct PaletteParser { @@ -42,7 +42,7 @@ impl Parser for Palet let vertical = reader.read_u16().await?; Ok(Command::GetPixel(canvas, horizontal, vertical)) } - SET_PX_BIN => { + SET_PX_PALETTE_BIN => { let canvas = reader.read_u8().await?; let horizontal = reader.read_u16().await?; let vertical = reader.read_u16().await?; From a91ca399a980d7b2bd044af7159da96398c0ea79 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 11:49:16 +0100 Subject: [PATCH 07/13] add test for parsing palette set command --- src/protocols/palette_protocol.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/protocols/palette_protocol.rs b/src/protocols/palette_protocol.rs index b122f35..ed60df3 100644 --- a/src/protocols/palette_protocol.rs +++ b/src/protocols/palette_protocol.rs @@ -103,4 +103,18 @@ impl Responder for PaletteParser { mod tests { use super::*; use tokio::io::BufReader; + + #[tokio::test] + async fn test_palette_px_set_parse() { + let parser = PaletteParser::default(); + let reader = tokio_test::io::Builder::new() + .read(&[SET_PX_PALETTE_BIN, 0x01, 0x69, 0x42, 0x42, 0x69, 0x82]) + .build(); + let mut bufreader = BufReader::new(reader); + let thingy = parser.parse(&mut bufreader).await.unwrap(); + assert_eq!( + thingy, + Command::SetPixel(1, 0x6942, 0x4269, parser.colors[0x82].clone()) + ); + } } From 232fe6b6e2b1c4c236a0914140e2ac7508374e3c Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 12:47:40 +0100 Subject: [PATCH 08/13] add response for protocol status --- src/lib.rs | 7 +++++++ src/protocols/binary_protocol.rs | 17 +++++++++++++++++ src/protocols/text_protocol.rs | 17 +++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 4b35c6f..ec943c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,12 @@ fn increment_counter(amount: u64) { COUNTER.fetch_add(amount, std::sync::atomic::Ordering::Relaxed); } +#[derive(Debug, PartialEq)] +pub enum ProtocolStatus { + Enabled(&'static str), + Disabled(&'static str), +} + #[derive(Debug, PartialEq)] pub enum Protocol { Text, @@ -72,6 +78,7 @@ pub enum Command { #[derive(Debug, PartialEq)] pub enum Response { Help, + Protocols(Vec), Size(Coordinate, Coordinate), GetPixel(Coordinate, Coordinate, [u8; 3]), } diff --git a/src/protocols/binary_protocol.rs b/src/protocols/binary_protocol.rs index e505112..b7c0996 100644 --- a/src/protocols/binary_protocol.rs +++ b/src/protocols/binary_protocol.rs @@ -106,6 +106,23 @@ To set a pixel using RGB, use ({SET_PX_RGB_BIN:02X}) (u8 canvas) (x as u16_le) ( ); writer.write_all(help_text.as_bytes()).await } + Response::Protocols(protos) => { + for protocol in protos { + match protocol { + crate::ProtocolStatus::Enabled(proto) => { + writer + .write_all(format!("Enabled: {}\n", proto).as_bytes()) + .await?; + } + crate::ProtocolStatus::Disabled(proto) => { + writer + .write_all(format!("Disabled: {}\n", proto).as_bytes()) + .await?; + } + } + } + Ok(()) + } Response::Size(x, y) => { writer.write_u16(x).await?; writer.write_u16(y).await diff --git a/src/protocols/text_protocol.rs b/src/protocols/text_protocol.rs index 1c711a2..f5e48bf 100644 --- a/src/protocols/text_protocol.rs +++ b/src/protocols/text_protocol.rs @@ -146,6 +146,23 @@ impl Responder for TextParser { async fn unparse(&self, response: Response, writer: &mut W) -> io::Result<()> { match response { Response::Help => writer.write_all(HELP_TEXT).await, + Response::Protocols(protos) => { + for protocol in protos { + match protocol { + crate::ProtocolStatus::Enabled(proto) => { + writer + .write_all(format!("Enabled: {}\n", proto).as_bytes()) + .await?; + } + crate::ProtocolStatus::Disabled(proto) => { + writer + .write_all(format!("Disabled: {}\n", proto).as_bytes()) + .await?; + } + } + } + Ok(()) + } Response::Size(x, y) => writer.write_all(format!("SIZE {x} {y}\n").as_bytes()).await, Response::GetPixel(x, y, color) => { writer From b52af7d44fdf815af06d2a10883f4b1a128a62dd Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 12:48:11 +0100 Subject: [PATCH 09/13] add command for protocols --- src/flutclient.rs | 22 +++++++++++++++++++++- src/lib.rs | 1 + 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/flutclient.rs b/src/flutclient.rs index ddd9f2f..fcbb0f2 100644 --- a/src/flutclient.rs +++ b/src/flutclient.rs @@ -10,7 +10,7 @@ use crate::{ grid::{self, Flut}, increment_counter, protocols::{BinaryParser, IOProtocol, Parser, Responder, TextParser}, - set_pixel_rgba, Canvas, Color, Command, Coordinate, Protocol, Response, + set_pixel_rgba, Canvas, Color, Command, Coordinate, Protocol, ProtocolStatus, Response, }; macro_rules! build_parser_type_enum { @@ -36,6 +36,17 @@ macro_rules! build_parser_type_enum { } impl ParserTypes { + pub fn get_status() -> Vec { + let mut protos = Vec::new(); + $( + #[cfg(feature = $feat)] + protos.push(ProtocolStatus::Enabled($feat)); + #[cfg(not(feature = $feat))] + protos.push(ProtocolStatus::Disabled($feat)); + )* + protos + } + pub fn announce() { $( #[cfg(feature = $feat)] @@ -88,6 +99,14 @@ where Ok(()) } + async fn protocols_command(&mut self) -> io::Result<()> { + match_parser! { + parser: self.parser => parser.unparse(Response::Protocols(ParserTypes::get_status()), &mut self.writer).await? + }; + self.writer.flush().await?; + 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( @@ -166,6 +185,7 @@ where match parsed { Ok(Command::Help) => self.help_command().await?, Ok(Command::Size(canvas)) => self.size_command(canvas).await?, + Ok(Command::Protocols) => self.protocols_command().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), Ok(Command::ChangeCanvas(canvas)) => { diff --git a/src/lib.rs b/src/lib.rs index ec943c7..ca49c1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,6 +68,7 @@ pub enum Protocol { #[derive(Debug, PartialEq)] pub enum Command { Help, + Protocols, Size(Canvas), GetPixel(Canvas, Coordinate, Coordinate), SetPixel(Canvas, Coordinate, Coordinate, Color), From 823f4a306a4dcc93133baf19af564154f4c16ec4 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 12:49:02 +0100 Subject: [PATCH 10/13] allow calling `Protocols` from BinaryParser --- src/protocols/binary_protocol.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/protocols/binary_protocol.rs b/src/protocols/binary_protocol.rs index b7c0996..5bb0a13 100644 --- a/src/protocols/binary_protocol.rs +++ b/src/protocols/binary_protocol.rs @@ -7,6 +7,7 @@ use crate::{Canvas, Color, Command, Response}; use super::{IOProtocol, Parser, Responder}; const SIZE_BIN: u8 = 115; +const PROTOCOLS_BIN: u8 = 116; const HELP_BIN: u8 = 104; const GET_PX_BIN: u8 = 32; const SET_PX_RGB_BIN: u8 = 128; @@ -22,6 +23,7 @@ impl Parser for Binar match fst { Ok(command) => match command { HELP_BIN => Ok(Command::Help), + PROTOCOLS_BIN => Ok(Command::Protocols), SIZE_BIN => { let canvas = reader.read_u8().await?; Ok(Command::Size(canvas)) From 6dc11526d836145e931d9a8d19cd35ba2e5056b0 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 12:50:34 +0100 Subject: [PATCH 11/13] allow calling `Protocols` from textparser --- src/protocols/text_protocol.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/protocols/text_protocol.rs b/src/protocols/text_protocol.rs index f5e48bf..0255e8f 100644 --- a/src/protocols/text_protocol.rs +++ b/src/protocols/text_protocol.rs @@ -117,6 +117,8 @@ impl Parser for TextP if reader.read_line(&mut line).await.is_ok() { if line.starts_with("HELP") { return Ok(Command::Help); + } else if line.starts_with("PROTOCOLS") { + return Ok(Command::Protocols); } else if line.starts_with("SIZE") { return Ok(Command::Size(self.canvas)); } else if line.starts_with("PX ") { From fe07344cb41f6013a4c7f975a31ccc11e2f2090d Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 12:55:05 +0100 Subject: [PATCH 12/13] use `vec![]` for the `get_status` vector --- src/flutclient.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/flutclient.rs b/src/flutclient.rs index fcbb0f2..f8a771a 100644 --- a/src/flutclient.rs +++ b/src/flutclient.rs @@ -37,14 +37,14 @@ macro_rules! build_parser_type_enum { impl ParserTypes { pub fn get_status() -> Vec { - let mut protos = Vec::new(); + vec![ $( #[cfg(feature = $feat)] - protos.push(ProtocolStatus::Enabled($feat)); + ProtocolStatus::Enabled($feat), #[cfg(not(feature = $feat))] - protos.push(ProtocolStatus::Disabled($feat)); + ProtocolStatus::Disabled($feat), )* - protos + ] } pub fn announce() { From 91d6a8a2e60ccd1cf3c168c971d1ff7022bea013 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Wed, 11 Dec 2024 13:04:44 +0100 Subject: [PATCH 13/13] add protocols support to `PaletteParser` --- src/protocols/palette_protocol.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/protocols/palette_protocol.rs b/src/protocols/palette_protocol.rs index ed60df3..992fedd 100644 --- a/src/protocols/palette_protocol.rs +++ b/src/protocols/palette_protocol.rs @@ -9,6 +9,7 @@ use crate::{Canvas, Color, Command, Response}; use super::{IOProtocol, Parser, Responder}; const SIZE_BIN: u8 = 115; +const PROTOCOLS_BIN: u8 = 116; const HELP_BIN: u8 = 104; const GET_PX_BIN: u8 = 32; const SET_PX_PALETTE_BIN: u8 = 33; @@ -32,6 +33,7 @@ impl Parser for Palet match fst { Ok(command) => match command { HELP_BIN => Ok(Command::Help), + PROTOCOLS_BIN => Ok(Command::Protocols), SIZE_BIN => { let canvas = reader.read_u8().await?; Ok(Command::Size(canvas)) @@ -85,6 +87,23 @@ impl Responder for PaletteParser { ) .await } + Response::Protocols(protos) => { + for protocol in protos { + match protocol { + crate::ProtocolStatus::Enabled(proto) => { + writer + .write_all(format!("Enabled: {}\n", proto).as_bytes()) + .await?; + } + crate::ProtocolStatus::Disabled(proto) => { + writer + .write_all(format!("Disabled: {}\n", proto).as_bytes()) + .await?; + } + } + } + Ok(()) + } Response::Size(x, y) => { writer.write_u16(x).await?; writer.write_u16(y).await