Skip to content

Commit 52bd0be

Browse files
authored
Merge pull request #24 from rursprung/add-support-for-alloc
add support for `alloc::vec::Vec`
2 parents d745ca6 + b12d67d commit 52bd0be

File tree

6 files changed

+55
-14
lines changed

6 files changed

+55
-14
lines changed

.github/workflows/CI.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
fail-fast: false
1212
matrix:
1313
rust: [1.62.0, stable]
14-
features: ['', '--all-features']
14+
features: ['use_alloc', 'use_alloc,defmt', 'use_heapless', 'use_heapless,defmt']
1515
runs-on: ubuntu-latest
1616
steps:
1717
- uses: actions/checkout@v4
@@ -21,15 +21,15 @@ jobs:
2121
toolchain: ${{ matrix.rust }}
2222
components: rustfmt clippy
2323
- name: build
24-
run: cargo build ${{ matrix.features }}
24+
run: cargo build --features ${{ matrix.features }}
2525
- name: check
26-
run: cargo check ${{ matrix.features }}
26+
run: cargo check --features ${{ matrix.features }}
2727
- name: test
28-
run: cargo test ${{ matrix.features }}
28+
run: cargo test --features ${{ matrix.features }}
2929
- name: check formatting
3030
run: cargo fmt --all -- --check
3131
- name: clippy
32-
run: cargo clippy ${{ matrix.features }}
32+
run: cargo clippy --features ${{ matrix.features }}
3333
- name: audit
3434
run: cargo audit
3535

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
<!-- next-header -->
88
## [Unreleased] - ReleaseDate
9+
### Added
10+
* Add support for using [`alloc::vec::Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)
911
### Changed
1012
* Due to dependency updates the MSRV has been updated from 1.60 to 1.62. This should only be relevant if you use the `defmt` feature, but we now only test with 1.62 and not older releases, so it's not guaranteed to work otherwise.
1113
* Update to `heapless:0.8.0`
14+
### Breaking Changes
15+
* You must now select either the feature `use_alloc` or `use_heapless` for the crate to compile. Select `use_heapless`
16+
to keep the API from the previous release of this crate.
1217

1318
## [0.1.1] - 2023-01-07
1419
### Changed

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ license = "MIT OR Apache-2.0"
1212

1313
[dependencies]
1414
defmt = { version = "0.3", optional = true }
15-
heapless = { version = "0.8" }
15+
heapless = { version = "0.8", optional = true }
1616

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

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

23-
defmt = ["dep:defmt", "heapless/defmt-03"]
23+
use_heapless = ["dep:heapless"]
24+
use_alloc = []
25+
26+
defmt = ["dep:defmt", "heapless?/defmt-03"]
2427

2528
accelerometer_event = []
2629
button_event = []

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ which is e.g. used by the [Adafruit Bluefruit LE UART Friend](https://learn.adaf
99

1010
Note that this work is not affiliated with Adafruit.
1111

12-
## Optional features
12+
## Mandatory Features
13+
This crate is `no_std` and you can choose whether you want to use
14+
[`heapless::Vec`](https://docs.rs/heapless/0.8.0/heapless/struct.Vec.html) by selecting the feature `use_heapless` or
15+
[`alloc::vec::Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html) by selecting the feature `use_alloc`.
16+
If you select neither or both you'll get a compile error.
17+
18+
## Optional Features
1319
* `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.
1420
* `rgb`: if enabled, `From<ColorEvent> for RGB8` is implemented to support the [RGB crate](https://crates.io/crates/rgb).
1521
* `serde`: if enabled, all events implement the [serde](https://serde.rs/) `#[derive(Serialize, Deserialize)]`.

examples/stm32f4-event-printer/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ defmt = "0.3.5"
1717
defmt-rtt = "0.4"
1818

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

2222
[profile.release]
2323
codegen-units = 1

src/lib.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@
2929
)))]
3030
compile_error!("at least one event type must be selected in the features!");
3131

32+
#[cfg(not(any(feature = "use_alloc", feature = "use_heapless")))]
33+
compile_error!("you must choose either 'use_alloc' or 'use_heapless' as a feature!");
34+
35+
#[cfg(all(feature = "use_alloc", feature = "use_heapless"))]
36+
compile_error!("you must choose either 'use_alloc' or 'use_heapless' as a feature but not both!");
37+
3238
#[cfg(feature = "accelerometer_event")]
3339
pub mod accelerometer_event;
3440
#[cfg(feature = "button_event")]
@@ -53,7 +59,13 @@ use color_event::ColorEvent;
5359
use core::cmp::min;
5460
#[cfg(feature = "gyro_event")]
5561
use gyro_event::GyroEvent;
62+
#[cfg(feature = "use_heapless")]
5663
use heapless::Vec;
64+
65+
#[cfg(feature = "use_alloc")]
66+
extern crate alloc;
67+
#[cfg(feature = "use_alloc")]
68+
use alloc::vec::Vec;
5769
#[cfg(feature = "location_event")]
5870
use location_event::LocationEvent;
5971
#[cfg(feature = "magnetometer_event")]
@@ -156,18 +168,27 @@ impl TryFrom<u8> for ControllerDataPackageType {
156168
}
157169
}
158170

171+
#[cfg(feature = "use_heapless")]
172+
type ParseResult<const MAX_RESULTS: usize> =
173+
Vec<Result<ControllerEvent, ProtocolParseError>, MAX_RESULTS>;
174+
175+
#[cfg(feature = "use_alloc")]
176+
type ParseResult<const MAX_RESULTS: usize> = Vec<Result<ControllerEvent, ProtocolParseError>>;
177+
#[cfg(feature = "use_alloc")]
178+
const MAX_RESULTS: usize = 0;
179+
159180
/// Parse the input string for commands. Unexpected content will be ignored if it's not formatted like a command!
160-
pub fn parse<const MAX_RESULTS: usize>(
181+
pub fn parse<#[cfg(feature = "use_heapless")] const MAX_RESULTS: usize>(
161182
input: &[u8],
162-
) -> Vec<Result<ControllerEvent, ProtocolParseError>, MAX_RESULTS> {
183+
) -> ParseResult<MAX_RESULTS> {
163184
/// Simple state machine for the parser, represents whether the parser is seeking a start or has found it.
164185
enum ParserState {
165186
SeekStart,
166187
ParseCommand,
167188
}
168189
let mut state = ParserState::SeekStart;
169190

170-
let mut result: Vec<Result<ControllerEvent, ProtocolParseError>, MAX_RESULTS> = Vec::new();
191+
let mut result = Vec::new();
171192

172193
for pos in 0..input.len() {
173194
let byte = input[pos];
@@ -179,7 +200,11 @@ pub fn parse<const MAX_RESULTS: usize>(
179200
}
180201
ParserState::ParseCommand => {
181202
let data_package = extract_and_parse_command(&input[(pos - 1)..]);
203+
#[cfg(feature = "use_alloc")]
204+
result.push(data_package);
205+
#[cfg(feature = "use_heapless")]
182206
result.push(data_package).ok();
207+
#[cfg(feature = "use_heapless")]
183208
if result.len() == MAX_RESULTS {
184209
return result;
185210
}
@@ -334,9 +359,11 @@ mod tests {
334359

335360
#[test]
336361
fn test_parse() {
337-
const MAX_RESULTS: usize = 4;
338362
let input = b"\x00!B11:!B10;\x00\x00!\x00\x00\x00\x00";
339-
let result = parse::<MAX_RESULTS>(input);
363+
#[cfg(feature = "use_heapless")]
364+
let result = parse::<4>(input);
365+
#[cfg(feature = "use_alloc")]
366+
let result = parse(input);
340367

341368
assert_eq!(result.len(), 3);
342369
assert_is_button_event(&result[0], Button::Button1, ButtonState::Pressed);

0 commit comments

Comments
 (0)