Skip to content
5 changes: 4 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{fs, path::PathBuf};
use anyhow::{Context, Result};
use badgemagic::{
ble::Device as BleDevice,
protocol::{Mode, PayloadBuffer, Speed, Style},
protocol::{Brightness, Mode, PayloadBuffer, Speed, Style},
usb_hid::Device as UsbDevice,
};
use base64::Engine;
Expand Down Expand Up @@ -63,6 +63,8 @@ enum TransportProtocol {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct Config {
#[serde(default)]
brightness: Option<Brightness>,
#[serde(rename = "message")]
messages: Vec<Message>,
}
Expand Down Expand Up @@ -148,6 +150,7 @@ fn gnerate_payload(args: &mut Args) -> Result<PayloadBuffer> {
};

let mut payload = PayloadBuffer::new();
payload.set_brightness(config.brightness.unwrap_or_default());

for message in config.messages {
let mut style = Style::default();
Expand Down
68 changes: 60 additions & 8 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Style {
self
}

/// Show a dotted border arround the display.
/// Show a dotted border around the display.
/// ```
/// use badgemagic::protocol::Style;
/// # (
Expand Down Expand Up @@ -161,7 +161,7 @@ impl TryFrom<u8> for Speed {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Mode {
/// Scroll thorugh the message from left to right
/// Scroll through the message from left to right
#[default]
Left,

Expand Down Expand Up @@ -193,14 +193,47 @@ pub enum Mode {
Laser,
}

/// Display Brightness
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Brightness {
#[default]
Full = 0x00,
ThreeQuarters = 0x10,
Half = 0x20,
OneQuarter = 0x30,
}

impl From<Brightness> for u8 {
fn from(value: Brightness) -> Self {
value as u8
}
}

impl TryFrom<u8> for Brightness {
type Error = TryFromIntError;

fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(match value {
0x00 => Self::Full,
0x10 => Self::ThreeQuarters,
0x20 => Self::Half,
0x30 => Self::OneQuarter,
_ => return Err(u8::try_from(-1).unwrap_err()),
})
}
}

const MSG_PADDING_ALIGN: usize = 64;

const MAGIC: [u8; 6] = *b"wang\0\0";
const MAGIC: [u8; 5] = *b"wang\0";

#[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C)]
struct Header {
magic: [u8; 6],
magic: [u8; 5],
brightness: u8,
blink: u8,
border: u8,
speed_and_mode: [u8; 8],
Expand Down Expand Up @@ -241,7 +274,7 @@ impl Timestamp {

/// Buffer to create a payload
///
/// A payload consits of up to 8 messages
/// A payload consists of up to 8 messages
/// ```
/// # #[cfg(feature = "embedded-graphics")]
/// # fn main() {
Expand All @@ -252,7 +285,7 @@ impl Timestamp {
/// primitives::{PrimitiveStyle, Rectangle, Styled},
/// };
///
/// let mut buffer = PayloadBuffer::new();
/// let mut buffer = PayloadBuffer::default();
/// buffer.add_message_drawable(
/// Style::default(),
/// &Styled::new(
Expand Down Expand Up @@ -283,6 +316,7 @@ impl PayloadBuffer {
num_messages: 0,
data: Header {
magic: MAGIC,
brightness: 0,
blink: 0,
border: 0,
speed_and_mode: [0; 8],
Expand All @@ -300,6 +334,10 @@ impl PayloadBuffer {
Header::mut_from_prefix(&mut self.data).unwrap().0
}

pub fn set_brightness(&mut self, brightness: Brightness) {
self.header_mut().brightness = brightness.into();
}

/// Return the current number of messages
pub fn num_messages(&mut self) -> usize {
self.num_messages as usize
Expand Down Expand Up @@ -368,7 +406,7 @@ impl PayloadBuffer {
&self.data
}
Comment on lines 430 to 431

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The num_messages method takes &mut self but does not mutate state.

Changing the receiver to &self would improve flexibility since no mutation occurs.

Suggested change
&self.data
}
/// Return the current number of messages
pub fn num_messages(&self) -> usize {
self.num_messages as usize
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this change set, but should be fixed 😅


/// Convert the payload buffe into bytes (with padding)
/// Convert the payload buffer into bytes (with padding)
#[allow(clippy::missing_panics_doc)] // should never panic
#[must_use]
pub fn into_padded_bytes(self) -> impl AsRef<[u8]> {
Expand Down Expand Up @@ -486,7 +524,7 @@ impl DrawTarget for MessageBuffer<'_> {
mod test {
use std::ops::Range;

use super::Speed;
use super::{Brightness, Speed};

#[test]
fn speed_to_u8_and_back() {
Expand All @@ -499,4 +537,18 @@ mod test {
}
}
}

#[test]
fn brightness_to_u8() {
const VALID_BRIGHTNESS_VALUES: [(Brightness, u8); 4] = [
(Brightness::Full, 0x00),
(Brightness::ThreeQuarters, 0x10),
(Brightness::Half, 0x20),
(Brightness::OneQuarter, 0x30),
];

for (value, raw) in VALID_BRIGHTNESS_VALUES {
assert_eq!(u8::from(value), raw);
}
}
}