Skip to content

Commit 34e5bfd

Browse files
committed
add possibility to only compile specific events
this yields smaller binary sizes (relevant on embedded devices).
1 parent 941a687 commit 34e5bfd

File tree

3 files changed

+96
-9
lines changed

3 files changed

+96
-9
lines changed

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,14 @@ heapless = { version = "0.7" }
1414
rgb = { version = "0.8", optional = true }
1515

1616
[features]
17+
default = ["accelerometer_event", "button_event", "color_event", "gyro_event", "location_event", "magnetometer_event", "quaternion_event"]
18+
1719
defmt = ["dep:defmt", "heapless/defmt-impl"]
20+
21+
accelerometer_event = []
22+
button_event = []
23+
color_event = []
24+
gyro_event = []
25+
location_event = []
26+
magnetometer_event = []
27+
quaternion_event = []

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ Note that this work is not affiliated with Adafruit.
99
## Optional features
1010
* `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.
1111
* `rgb`: if enabled, the `ColorEvent` implements `Into<RGB8>` for the [RGB crate](https://crates.io/crates/rgb).
12+
* All events can be selected as individual features. By default, they are all selected,
13+
but you can opt to only select the event(s) you are interested in which will result in a small binary size.
14+
If other events are received, a `ProtocolParseError::DisabledControllerDataPackageType` will be returned.

src/lib.rs

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
//! ## Optional features
55
//! * `defmt`: you can enable the `defmt` feature to get a `defmt::Format` implementation for all structs & enums and a `defmt::debug!` call for each command being parsed.
66
//! * `rgb`: if enabled, the `ColorEvent` implements `Into<RGB8>` for the [RGB crate](https://crates.io/crates/rgb).
7+
//! * All events can be selected as individual features. By default, they are all selected,
8+
//! but you can opt to only select the event(s) you are interested in which will result in a small binary size.
9+
//! If other events are received, a [`ProtocolParseError::DisabledControllerDataPackageType`] will be returned.
710
811
#![forbid(unsafe_code)]
912
// use deny instead of forbid due to bogus warnings, see also https://github.com/rust-lang/rust/issues/81670
@@ -14,35 +17,67 @@
1417
#![deny(unused)]
1518
#![no_std]
1619

20+
#[cfg(not(any(
21+
feature = "accelerometer_event",
22+
feature = "button_event",
23+
feature = "color_event",
24+
feature = "gyro_event",
25+
feature = "location_event",
26+
feature = "magnetometer_event",
27+
feature = "quaternion_event"
28+
)))]
29+
compile_error!("at least one event type must be selected in the features!");
30+
31+
#[cfg(feature = "accelerometer_event")]
1732
pub mod accelerometer_event;
33+
#[cfg(feature = "button_event")]
1834
pub mod button_event;
35+
#[cfg(feature = "color_event")]
1936
pub mod color_event;
37+
#[cfg(feature = "gyro_event")]
2038
pub mod gyro_event;
39+
#[cfg(feature = "location_event")]
2140
pub mod location_event;
41+
#[cfg(feature = "magnetometer_event")]
2242
pub mod magnetometer_event;
43+
#[cfg(feature = "quaternion_event")]
2344
pub mod quaternion_event;
2445

46+
#[cfg(feature = "accelerometer_event")]
2547
use accelerometer_event::AccelerometerEvent;
48+
#[cfg(feature = "button_event")]
2649
use button_event::{ButtonEvent, ButtonParseError};
50+
#[cfg(feature = "color_event")]
2751
use color_event::ColorEvent;
2852
use core::cmp::min;
53+
#[cfg(feature = "gyro_event")]
2954
use gyro_event::GyroEvent;
3055
use heapless::Vec;
56+
#[cfg(feature = "location_event")]
3157
use location_event::LocationEvent;
58+
#[cfg(feature = "magnetometer_event")]
3259
use magnetometer_event::MagnetometerEvent;
60+
#[cfg(feature = "quaternion_event")]
3361
use quaternion_event::QuaternionEvent;
3462

3563
/// Lists all (supported) events which can be sent by the controller. These come with the parsed event data and are the result of a [`parse`] call.
3664
#[derive(PartialEq, Debug)]
3765
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3866
#[allow(missing_docs)] // the names are already obvious enough
3967
pub enum ControllerEvent {
68+
#[cfg(feature = "button_event")]
4069
ButtonEvent(ButtonEvent),
70+
#[cfg(feature = "color_event")]
4171
ColorEvent(ColorEvent),
72+
#[cfg(feature = "quaternion_event")]
4273
QuaternionEvent(QuaternionEvent),
74+
#[cfg(feature = "accelerometer_event")]
4375
AccelerometerEvent(AccelerometerEvent),
76+
#[cfg(feature = "gyro_event")]
4477
GyroEvent(GyroEvent),
78+
#[cfg(feature = "magnetometer_event")]
4579
MagnetometerEvent(MagnetometerEvent),
80+
#[cfg(feature = "location_event")]
4681
LocationEvent(LocationEvent),
4782
}
4883

@@ -52,7 +87,10 @@ pub enum ControllerEvent {
5287
pub enum ProtocolParseError {
5388
/// The message contained an event which is not known to the current implementation. This can either mean that the message was malformed or that a newer protocol version has been used.
5489
UnknownEvent(Option<u8>),
90+
/// 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.
91+
DisabledControllerDataPackageType(ControllerDataPackageType),
5592
/// An error occurred while parsing a [`ButtonEvent`].
93+
#[cfg(feature = "button_event")]
5694
ButtonParseError(ButtonParseError),
5795
/// The event in the message did not have the expected length.
5896
InvalidLength(usize, usize),
@@ -66,7 +104,7 @@ pub enum ProtocolParseError {
66104
#[derive(PartialEq, Eq, Debug)]
67105
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
68106
#[allow(missing_docs)] // the names are already obvious enough
69-
enum ControllerDataPackageType {
107+
pub enum ControllerDataPackageType {
70108
ButtonCommand,
71109
Color,
72110
Quaternion,
@@ -185,27 +223,62 @@ fn parse_command(
185223
let data = &command_input[data_start..=data_end];
186224
match command {
187225
ControllerDataPackageType::ButtonCommand => {
188-
ButtonEvent::try_from(data).map(ControllerEvent::ButtonEvent)
226+
#[cfg(feature = "button_event")]
227+
return ButtonEvent::try_from(data).map(ControllerEvent::ButtonEvent);
228+
#[cfg(not(feature = "button_event"))]
229+
return Err(ProtocolParseError::DisabledControllerDataPackageType(
230+
command,
231+
));
189232
}
190233
ControllerDataPackageType::Color => {
191-
ColorEvent::try_from(data).map(ControllerEvent::ColorEvent)
234+
#[cfg(feature = "color_event")]
235+
return ColorEvent::try_from(data).map(ControllerEvent::ColorEvent);
236+
#[cfg(not(feature = "color_event"))]
237+
return Err(ProtocolParseError::DisabledControllerDataPackageType(
238+
command,
239+
));
192240
}
193241
ControllerDataPackageType::Quaternion => {
194-
QuaternionEvent::try_from(data).map(ControllerEvent::QuaternionEvent)
242+
#[cfg(feature = "quaternion_event")]
243+
return QuaternionEvent::try_from(data).map(ControllerEvent::QuaternionEvent);
244+
#[cfg(not(feature = "quaternion_event"))]
245+
return Err(ProtocolParseError::DisabledControllerDataPackageType(
246+
command,
247+
));
195248
}
196249
ControllerDataPackageType::Accelerometer => {
197-
AccelerometerEvent::try_from(data).map(ControllerEvent::AccelerometerEvent)
250+
#[cfg(feature = "accelerometer_event")]
251+
return AccelerometerEvent::try_from(data).map(ControllerEvent::AccelerometerEvent);
252+
#[cfg(not(feature = "accelerometer_event"))]
253+
return Err(ProtocolParseError::DisabledControllerDataPackageType(
254+
command,
255+
));
198256
}
199257
ControllerDataPackageType::Gyro => {
200-
GyroEvent::try_from(data).map(ControllerEvent::GyroEvent)
258+
#[cfg(feature = "gyro_event")]
259+
return GyroEvent::try_from(data).map(ControllerEvent::GyroEvent);
260+
#[cfg(not(feature = "gyro_event"))]
261+
return Err(ProtocolParseError::DisabledControllerDataPackageType(
262+
command,
263+
));
201264
}
202265
ControllerDataPackageType::Magnetometer => {
203-
MagnetometerEvent::try_from(data).map(ControllerEvent::MagnetometerEvent)
266+
#[cfg(feature = "magnetometer_event")]
267+
return MagnetometerEvent::try_from(data).map(ControllerEvent::MagnetometerEvent);
268+
#[cfg(not(feature = "magnetometer_event"))]
269+
return Err(ProtocolParseError::DisabledControllerDataPackageType(
270+
command,
271+
));
204272
}
205273
ControllerDataPackageType::Location => {
206-
LocationEvent::try_from(data).map(ControllerEvent::LocationEvent)
274+
#[cfg(feature = "location_event")]
275+
return LocationEvent::try_from(data).map(ControllerEvent::LocationEvent);
276+
#[cfg(not(feature = "location_event"))]
277+
return Err(ProtocolParseError::DisabledControllerDataPackageType(
278+
command,
279+
));
207280
}
208-
}
281+
};
209282
}
210283

211284
/// Check the CRC of a command
@@ -228,6 +301,7 @@ fn check_crc(data: &[u8], crc: &u8) -> Result<(), ProtocolParseError> {
228301
}
229302

230303
/// Small wrapper to convert the 4-byte value to an `f32` and handle the error.
304+
#[allow(unused)] // can be unused if no event which needs this has been selected as a feature.
231305
fn try_f32_from_le_bytes(input: &[u8]) -> Result<f32, ProtocolParseError> {
232306
Ok(f32::from_le_bytes(<[u8; 4]>::try_from(input).map_err(
233307
|_| ProtocolParseError::InvalidFloatSize(input.len()),

0 commit comments

Comments
 (0)