Skip to content

Commit

Permalink
Merge pull request #38 from rursprung/prepare-v0.3.0
Browse files Browse the repository at this point in the history
prepare v0.3.0: change API to Iterator, implement `core::error::Error` & add some `Copy`, `Clone`, `Hash` where applicable
  • Loading branch information
rursprung authored Oct 13, 2024
2 parents 5856dca + 6240970 commit 53187a6
Show file tree
Hide file tree
Showing 15 changed files with 214 additions and 150 deletions.
31 changes: 20 additions & 11 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@ jobs:
strategy:
fail-fast: false
matrix:
rust: [1.62.0, stable]
features: ['use_alloc', 'use_alloc,defmt', 'use_heapless', 'use_heapless,defmt']
exclude:
- rust: 1.62.0
features: 'use_alloc,defmt'
- rust: 1.62.0
features: 'use_heapless,defmt'
rust: [1.81.0, stable]
features: ['']
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -31,17 +26,17 @@ jobs:
- name: Install required cargo components
run: cargo +stable install clippy-sarif sarif-fmt
- name: build
run: cargo build --features ${{ matrix.features }}
run: cargo build ${{ matrix.features }}
- name: check
run: cargo check --features ${{ matrix.features }}
run: cargo check ${{ matrix.features }}
- name: test
run: cargo test --features ${{ matrix.features }}
run: cargo test ${{ matrix.features }}
- name: check formatting
run: cargo fmt --all -- --check
- name: audit
run: cargo audit
- name: clippy (lib)
run: cargo clippy --features ${{ matrix.features }} --message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt
run: cargo clippy ${{ matrix.features }} --message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt
continue-on-error: true
- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v3
Expand Down Expand Up @@ -87,3 +82,17 @@ jobs:
with:
sarif_file: examples/stm32f4-event-printer/rust-clippy-results.sarif
wait-for-processing: true

# simplify GH settings: have one single build to be required
build-results:
name: Final Results
if: ${{ always() }}
runs-on: ubuntu-latest
needs: [lib, stm32f4-event-printer]
steps:
- name: check for failed builds of the library
if: ${{ needs.lib.result != 'success' }}
run: exit 1
- name: check for failed builds of the example
if: ${{ needs.stm32f4-event-printer.result != 'success' }}
run: exit 1
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- next-header -->
## [Unreleased] - ReleaseDate
### Added
* `Copy`, `Clone` and `Hash` on error & event types (where possible)
### Changed
* The MSRV has been updated to 1.81.0 due to `core::error::Error` being implemented
* **BREAKING**: The `parse` API has been replaced with `Parser::new` where `Parser` now implements `Iterator` and the `next` function returns each parsed command
* Accordingly, the features `use_alloc` and `use_heapless` have been removed.

## [0.2.0] - 2023-11-14
### Added
Expand Down
8 changes: 2 additions & 6 deletions 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 All @@ -12,18 +12,14 @@ license = "MIT OR Apache-2.0"

[dependencies]
defmt = { version = "0.3", optional = true }
heapless = { version = "0.8", optional = true }

rgb = { version = "0.8", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }

[features]
default = ["accelerometer_event", "button_event", "color_event", "gyro_event", "location_event", "magnetometer_event", "quaternion_event"]

use_heapless = ["dep:heapless"]
use_alloc = []

defmt = ["dep:defmt", "heapless?/defmt-03"]
defmt = ["dep:defmt"]

accelerometer_event = []
button_event = []
Expand Down
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ which is e.g. used by the [Adafruit Bluefruit LE UART Friend](https://learn.adaf

Note that this work is not affiliated with Adafruit.

## Mandatory Features
This crate is `no_std` and you can choose whether you want to use
[`heapless::Vec`](https://docs.rs/heapless/0.8.0/heapless/struct.Vec.html) by selecting the feature `use_heapless` or
[`alloc::vec::Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html) by selecting the feature `use_alloc`.
If you select neither or both you'll get a compile error.

## Optional Features
* `defmt`: you can enable the [`defmt`](https://defmt.ferrous-systems.com/) feature to get a `defmt::Format` implementation for all structs & enums and a `defmt::debug!` call for each command being parsed.
* `rgb`: if enabled, `From<ColorEvent> for RGB8` is implemented to support the [RGB crate](https://crates.io/crates/rgb).
Expand All @@ -23,12 +17,16 @@ If you select neither or both you'll get a compile error.
but you can opt to only select the event(s) you are interested in which will result in a small binary size.
If other events are received, a `ProtocolParseError::DisabledControllerDataPackageType` will be returned.

## Usage
The entry point to use this crate is `Parser` which implements `Iterator` to access the events in the input.
Note that this is a [sans I/O](https://sans-io.readthedocs.io/) crate, i.e. you have to talk to the Adafruit device, the parser just expects a byte sequence.

## Examples
A simple example for the STM32F4 microcontrollers is [available](examples/stm32f4-event-printer/README.md).

## Changelog
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.
25 changes: 2 additions & 23 deletions examples/stm32f4-event-printer/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/stm32f4-event-printer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmt = "0.3.6"
defmt-rtt = "0.4"

# use `adafruit-bluefruit-protocol = "0.1"` in reality; path used here to ensure that the example always compiles against the latest master
adafruit-bluefruit-protocol = { path = "../..", features = ["defmt", "use_heapless"] }
adafruit-bluefruit-protocol = { path = "../..", features = ["defmt"] }

[profile.release]
codegen-units = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ impl BluefruitLEUARTFriend {
filled_buffer
);

let event = adafruit_bluefruit_protocol::parse::<4>(filled_buffer);
defmt::info!("received event(s) over bluetooth: {}", &event);
let parser = adafruit_bluefruit_protocol::Parser::new(filled_buffer);
for event in parser {
defmt::info!("received event over bluetooth: {:?}", &event);
}

// switch out the buffers
filled_buffer.fill(0);
Expand Down
2 changes: 1 addition & 1 deletion src/accelerometer_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use super::{try_f32_from_le_bytes, ProtocolParseError};

/// Represents an accelerometer event from the protocol.
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[allow(missing_docs)] // the names are already obvious enough
Expand Down
22 changes: 18 additions & 4 deletions src/button_event.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! 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)]
#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ButtonParseError {
/// The message contained an unknown button. For the known buttons see [`Button`].
Expand All @@ -12,8 +14,20 @@ 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)]
#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[allow(missing_docs)] // the names are already obvious enough
pub enum Button {
Expand Down Expand Up @@ -45,7 +59,7 @@ impl Button {
}

/// The state of the button.
#[derive(PartialEq, Eq, Debug)]
#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[allow(missing_docs)] // the names are already obvious enough
Expand All @@ -66,7 +80,7 @@ impl ButtonState {
}

/// Represents a button event from the protocol.
#[derive(PartialEq, Eq, Debug)]
#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[allow(missing_docs)] // the names are already obvious enough
pub struct ButtonEvent {
Expand Down
2 changes: 1 addition & 1 deletion src/color_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::ProtocolParseError;
use rgb::RGB8;

/// Represents a color event from the protocol.
#[derive(PartialEq, Eq, Debug)]
#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[allow(missing_docs)] // the names are already obvious enough
Expand Down
2 changes: 1 addition & 1 deletion src/gyro_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use super::{try_f32_from_le_bytes, ProtocolParseError};

/// Represents a gyro event from the protocol.
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[allow(missing_docs)] // the names are already obvious enough
Expand Down
Loading

0 comments on commit 53187a6

Please sign in to comment.