From c4c67085334571a36f8c5c3ff851d72ee2df4608 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 23 Jun 2024 10:43:23 +0200 Subject: [PATCH] limit brightness to valid levels, optional rand dependency to implement Distribution trait fixup! limit brightness to valid levels, optional rand dependency to implement Distribution trait --- crates/servicepoint/Cargo.toml | 8 +++- .../examples/random_brightness.rs | 4 +- crates/servicepoint/src/brightness.rs | 41 +++++++++++++++++++ crates/servicepoint/src/command.rs | 26 ++++++------ crates/servicepoint/src/lib.rs | 4 +- 5 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 crates/servicepoint/src/brightness.rs diff --git a/crates/servicepoint/Cargo.toml b/crates/servicepoint/Cargo.toml index ac2698f..b68b538 100644 --- a/crates/servicepoint/Cargo.toml +++ b/crates/servicepoint/Cargo.toml @@ -19,6 +19,7 @@ flate2 = { version = "1.0", optional = true } bzip2 = { version = "0.4", optional = true } zstd = { version = "0.13", optional = true } rust-lzma = { version = "0.6.0", optional = true } +rand = { version = "0.8", optional = true } [features] default = ["compression_lzma"] @@ -27,6 +28,11 @@ compression_bzip2 = ["dep:bzip2"] compression_lzma = ["dep:rust-lzma"] compression_zstd = ["dep:zstd"] all_compressions = ["compression_zlib", "compression_bzip2", "compression_lzma", "compression_zstd"] +rand = ["dep:rand"] + +[[example]] +name = "random_brightness" +required-features = ["rand"] [dev-dependencies] # for examples @@ -34,4 +40,4 @@ clap = { version = "4.5", features = ["derive"] } rand = "0.8" [lints] -workspace = true +workspace = true \ No newline at end of file diff --git a/crates/servicepoint/examples/random_brightness.rs b/crates/servicepoint/examples/random_brightness.rs index ad3dfae..d37b7f2 100644 --- a/crates/servicepoint/examples/random_brightness.rs +++ b/crates/servicepoint/examples/random_brightness.rs @@ -32,7 +32,7 @@ fn main() { filled_grid.fill(true); let command = - BitmapLinearWin(Origin(0, 0), filled_grid, CompressionCode::Lzma); + BitmapLinearWin(Origin::new(0, 0), filled_grid, CompressionCode::Lzma); connection.send(command).expect("send failed"); } @@ -49,7 +49,7 @@ fn main() { let w = rng.gen_range(min_size..=TILE_WIDTH - x); let h = rng.gen_range(min_size..=TILE_HEIGHT - y); - let origin = Origin(x, y); + let origin = Origin::new(x, y); let mut luma = ByteGrid::new(w, h); for y in 0..h { diff --git a/crates/servicepoint/src/brightness.rs b/crates/servicepoint/src/brightness.rs new file mode 100644 index 0000000..b95c2dd --- /dev/null +++ b/crates/servicepoint/src/brightness.rs @@ -0,0 +1,41 @@ +use rand::distributions::Standard; +#[cfg(feature = "rand")] +use rand::prelude::Distribution; +#[cfg(feature = "rand")] +use rand::Rng; + +/// A display brightness value, checked for correct value range +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct Brightness(u8); + +impl From for u8 { + fn from(brightness: Brightness) -> Self { + brightness.0 + } +} + +impl TryFrom for Brightness { + type Error = (); + + fn try_from(value: u8) -> Result { + if value > Self::MAX.0 { + Err(()) + } else { + Ok(Brightness(value)) + } + } +} + +impl Brightness { + /// highest possible brightness value, 11 + pub const MAX: Brightness = Brightness(11); + /// lowest possible brightness value, 0 + pub const MIN: Brightness = Brightness(0); +} + +#[cfg(feature = "rand")] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> Brightness { + Brightness(rng.gen_range(Brightness::MIN.0..(Brightness::MAX.0 + 1))) + } +} diff --git a/crates/servicepoint/src/command.rs b/crates/servicepoint/src/command.rs index b488426..a05032d 100644 --- a/crates/servicepoint/src/command.rs +++ b/crates/servicepoint/src/command.rs @@ -3,8 +3,8 @@ use bitvec::prelude::BitVec; use crate::command_code::CommandCode; use crate::compression::{into_compressed, into_decompressed}; use crate::{ - ByteGrid, CompressionCode, Grid, Header, Packet, PixelGrid, SpBitVec, - TILE_SIZE, + Brightness, ByteGrid, CompressionCode, Grid, Header, Packet, PixelGrid, + SpBitVec, TILE_SIZE, }; /// An origin marks the top left position of a window sent to the display. @@ -24,9 +24,6 @@ impl std::ops::Add for Origin { /// Type alias for documenting the meaning of the u16 in enum values pub type Offset = usize; -/// Type alias for documenting the meaning of the u16 in enum values -pub type Brightness = u8; - /// A command to send to the display. #[derive(Debug, Clone, PartialEq)] pub enum Command { @@ -95,7 +92,7 @@ impl From for Packet { 0x0000, 0x0000, ), - vec![brightness], + vec![brightness.into()], ), Command::BitmapLinearWin(origin, pixels, compression) => { bitmap_win_into_packet(origin, pixels, compression) @@ -196,6 +193,8 @@ pub enum TryFromPacketError { InvalidCompressionCode(u16), /// Decompression of the payload failed. This can be caused by corrupted packets. DecompressionFailed, + /// The given brightness value is out of bounds + InvalidBrightness(u8), } impl TryFrom for Command { @@ -227,9 +226,12 @@ impl TryFrom for Command { let Header(_, a, b, c, d) = header; if a != 0 || b != 0 || c != 0 || d != 0 { - Err(TryFromPacketError::ExtraneousHeaderValues) - } else { - Ok(Command::Brightness(payload[0])) + return Err(TryFromPacketError::ExtraneousHeaderValues) + } + + match Brightness::try_from(payload[0]) { + Ok(b) => Ok(Command::Brightness(b)), + Err(_) => Err(TryFromPacketError::InvalidBrightness(payload[0])) } } CommandCode::HardReset => match Self::check_command_only(packet) { @@ -399,9 +401,7 @@ mod tests { use crate::command::TryFromPacketError; use crate::command_code::CommandCode; - use crate::{ - ByteGrid, Command, CompressionCode, Header, Origin, Packet, PixelGrid, - }; + use crate::{Brightness, ByteGrid, Command, CompressionCode, Header, Origin, Packet, PixelGrid}; fn round_trip(original: Command) { let packet: Packet = original.clone().into(); @@ -443,7 +443,7 @@ mod tests { #[test] fn round_trip_brightness() { - round_trip(Command::Brightness(6)); + round_trip(Command::Brightness(Brightness::try_from(6).unwrap())); } #[test] diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs index dcb2755..6a0a5e5 100644 --- a/crates/servicepoint/src/lib.rs +++ b/crates/servicepoint/src/lib.rs @@ -5,8 +5,9 @@ use std::time::Duration; pub use bitvec; use bitvec::prelude::{BitVec, Msb0}; +pub use crate::brightness::Brightness; pub use crate::byte_grid::ByteGrid; -pub use crate::command::{Brightness, Command, Offset, Origin}; +pub use crate::command::{Command, Offset, Origin}; pub use crate::compression_code::CompressionCode; pub use crate::connection::Connection; pub use crate::data_ref::DataRef; @@ -16,6 +17,7 @@ pub use crate::pixel_grid::PixelGrid; type SpBitVec = BitVec; +mod brightness; mod byte_grid; mod command; mod command_code;