Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ jobs:
strategy:
fail-fast: false
matrix:
rust: [1.62.0, stable]
rust: [1.81.0, stable]
features: ['use_alloc', 'use_alloc,defmt', 'use_heapless', 'use_heapless,defmt']
exclude:
- rust: 1.62.0
- rust: 1.81.0
features: 'use_alloc,defmt'
- rust: 1.62.0
- rust: 1.81.0
features: 'use_heapless,defmt'
runs-on: ubuntu-latest
steps:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- next-header -->
## [Unreleased] - ReleaseDate
### Changed
* The MSRV has been updated to 1.81.0 due to `core::error::Error` being implemented

## [0.2.0] - 2023-11-14
### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "adafruit-bluefruit-protocol"
version = "0.2.0"
edition = "2021"
rust-version = "1.62"
rust-version = "1.81"

description = "A `no_std` parser for the Adafruit Bluefruit LE Connect controller protocol."
repository = "https://github.com/rust-embedded-community/adafruit-bluefruit-protocol-rs"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ A simple example for the STM32F4 microcontrollers is [available](examples/stm32f
For the changelog please see the dedicated [CHANGELOG.md](CHANGELOG.md).

## Minimum Supported Rust Version (MSRV)
This crate is guaranteed to compile on stable Rust 1.62 and up. It *might*
This crate is guaranteed to compile on stable Rust 1.81 and up. It *might*
compile with older versions but that may change in any new patch release.
14 changes: 14 additions & 0 deletions src/button_event.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Implements the [`ButtonEvent`] and its parsing from the protocol.

use super::ProtocolParseError;
use core::error::Error;
use core::fmt::{Display, Formatter};

/// Errors which can be raised while parsing a button event.
#[derive(PartialEq, Eq, Debug)]
Expand All @@ -12,6 +14,18 @@ pub enum ButtonParseError {
UnknownButtonState(u8),
}

impl Display for ButtonParseError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
use ButtonParseError::*;
match self {
UnknownButton(button) => write!(f, "Unknown button: {:#x}", button),
UnknownButtonState(state) => write!(f, "Unknown button state: {:#x}", state),
}
}
}

impl Error for ButtonParseError {}

/// Lists all possible buttons which can be sent in the event.
#[derive(PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
Expand Down
66 changes: 61 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ use heapless::Vec;
extern crate alloc;
#[cfg(feature = "use_alloc")]
use alloc::vec::Vec;
use core::error::Error;
use core::fmt::{Display, Formatter};
#[cfg(feature = "location_event")]
use location_event::LocationEvent;
#[cfg(feature = "magnetometer_event")]
Expand Down Expand Up @@ -101,8 +103,7 @@ pub enum ProtocolParseError {
/// The message contained an event which is not known to the current implementation.
/// This can mean that:
/// * the message was malformed or
/// * that a newer protocol version has been used or
/// * that the event type has not been enabled as a feature.
/// * that a newer protocol version has been used.
UnknownEvent(Option<u8>),
/// The message contained an event which is known to the library but has not been selected as a feature and can thus not be parsed. Select the feature when compiling the library to handle this message.
DisabledControllerDataPackageType(ControllerDataPackageType),
Expand All @@ -117,6 +118,44 @@ pub enum ProtocolParseError {
InvalidFloatSize(usize),
}

impl Display for ProtocolParseError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
use ProtocolParseError::*;
match self {
UnknownEvent(event) => write!(f, "Unknown event type: {:?}", event),
DisabledControllerDataPackageType(event) => {
write!(f, "Disabled event type: {:?}", event)
}
ButtonParseError(_) => write!(f, "Error while parsing button event"),
InvalidLength(expected, actual) => write!(
f,
"Invalid message length: expected {} but received {}",
expected, actual
),
InvalidCrc(expected, actual) => write!(
f,
"Invalid CRC: expected {:#x} but calculated {:#x}",
expected, actual
),
InvalidFloatSize(length) => write!(
f,
"Failed to parse float from a message with size {}",
length
),
}
}
}

impl Error for ProtocolParseError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
use ProtocolParseError::*;
match self {
ButtonParseError(e) => Some(e),
_ => None,
}
}
}

/// Lists all data packages which can be sent by the controller. Internal state used during parsing. Use [`ControllerEvent`] to return the actual event.
#[derive(PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
Expand Down Expand Up @@ -340,7 +379,7 @@ fn try_f32_from_le_bytes(input: &[u8]) -> Result<f32, ProtocolParseError> {

#[cfg(test)]
mod tests {
use crate::button_event::{Button, ButtonState};
use crate::button_event::{Button, ButtonParseError, ButtonState};
use crate::{check_crc, parse, try_f32_from_le_bytes, ControllerEvent, ProtocolParseError};

fn assert_is_button_event(
Expand All @@ -359,16 +398,33 @@ mod tests {

#[test]
fn test_parse() {
let input = b"\x00!B11:!B10;\x00\x00!\x00\x00\x00\x00";
let input = b"\x00!B11:!B10;\x00\x00!\x00\x00\x00\x00!B138";
#[cfg(feature = "use_heapless")]
let result = parse::<4>(input);
#[cfg(feature = "use_alloc")]
let result = parse(input);

assert_eq!(result.len(), 3);
assert_eq!(result.len(), 4);
assert_is_button_event(&result[0], Button::Button1, ButtonState::Pressed);
assert_is_button_event(&result[1], Button::Button1, ButtonState::Released);
assert_eq!(result[2], Err(ProtocolParseError::UnknownEvent(Some(0))));
if let Err(e) = &result[3] {
assert_eq!(
e,
&ProtocolParseError::ButtonParseError(ButtonParseError::UnknownButtonState(b'3'))
);
#[cfg(feature = "use_alloc")]
{
use alloc::string::ToString;
use core::error::Error;
assert_eq!(
e.source().unwrap().to_string(),
"Unknown button state: 0x33"
);
}
} else {
assert!(false, "expected an error");
}
}

#[test]
Expand Down