#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[allow(unused_qualifications)]
pub struct StateSet {
firmware: crate::headers::InternalFirmware,
raw: ::bitvec::array::BitArray<u32, ::bitvec::order::Lsb0>,
}
#[allow(unused_qualifications, clippy::cast_possible_truncation)]
impl StateSet {
pub(crate) fn new(raw: u32, firmware: crate::headers::InternalFirmware) -> Self {
Self {
firmware,
raw: ::bitvec::array::BitArray::new(raw),
}
}
fn iter(&self) -> impl Iterator<Item = <Self as crate::units::FlagSet>::Flag> + '_ {
self.raw
.iter_ones()
.filter_map(|bit| <State>::from_bit(bit as u32, self.firmware))
}
}
#[allow(unused_qualifications, clippy::cast_possible_truncation)]
impl crate::units::FlagSet for StateSet {
type Flag = State;
fn is_set(&self, flag: Self::Flag) -> bool {
flag.to_bit(self.firmware)
.map_or(false, |bit| self.raw[bit as usize])
}
fn as_names(&self) -> ::alloc::vec::Vec<&'static str> {
self.iter()
.map(|flag| <State as crate::units::Flag>::as_name(&flag))
.collect()
}
}
#[allow(unused_qualifications)]
impl ::core::fmt::Display for StateSet {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
let names = <Self as crate::units::FlagSet>::as_names(self);
f.write_str(&names.join("|"))
}
}
#[cfg(feature = "_serde")]
#[allow(clippy::cast_possible_truncation)]
impl ::serde::Serialize for StateSet {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(None)?;
for flag in self.iter() {
seq.serialize_element(&flag)?;
}
seq.end()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "_serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum State {
AccelerometerCalibrated,
AirMode,
Airplane,
AltitudeControl,
AntiWindup,
AntiWindupDeactivated,
Boat,
CalibrateMag,
CompassCalibrated,
EscSensorEnabled,
FixedWingLegacy,
FlaperonAvailable,
FwHeadingUseYaw,
GpsEstimatedFix,
GpsFix,
GpsFixEver,
GpsFixHome,
InFlightEmergencyRearm,
LandingDetected,
MoveForwardOnly,
Multirotor,
NavCruiseBraking,
NavCruiseBrakingBoost,
NavCruiseBrakingLocked,
NavExtraArmingSafetyBypassed,
NavMotorStopOrIdle,
Rover,
SetReversibleMotorsForward,
SmallAngle,
Tailsitter,
}
#[allow(unused_qualifications)]
impl crate::units::Flag for State {
fn as_name(&self) -> &'static str {
match self {
Self::AccelerometerCalibrated => "ACCELEROMETER_CALIBRATED",
Self::AirMode => "AIRMODE_ACTIVE",
Self::Airplane => "AIRPLANE",
Self::AltitudeControl => "ALTITUDE_CONTROL",
Self::AntiWindup => "ANTI_WINDUP",
Self::AntiWindupDeactivated => "ANTI_WINDUP_DEACTIVATED",
Self::Boat => "BOAT",
Self::CalibrateMag => "CALIBRATE_MAG",
Self::CompassCalibrated => "COMPASS_CALIBRATED",
Self::EscSensorEnabled => "ESC_SENSOR_ENABLED",
Self::FixedWingLegacy => "FIXED_WING_LEGACY",
Self::FlaperonAvailable => "FLAPERON_AVAILABLE",
Self::FwHeadingUseYaw => "FW_HEADING_USE_YAW",
Self::GpsEstimatedFix => "GPS_ESTIMATED_FIX",
Self::GpsFix => "GPS_FIX",
Self::GpsFixEver => "GPS_FIX_EVER",
Self::GpsFixHome => "GPS_FIX_HOME",
Self::InFlightEmergencyRearm => "IN_FLIGHT_EMERG_REARM",
Self::LandingDetected => "LANDING_DETECTED",
Self::MoveForwardOnly => "MOVE_FORWARD_ONLY",
Self::Multirotor => "MULTIROTOR",
Self::NavCruiseBraking => "NAV_CRUISE_BRAKING",
Self::NavCruiseBrakingBoost => "NAV_CRUISE_BRAKING_BOOST",
Self::NavCruiseBrakingLocked => "NAV_CRUISE_BRAKING_LOCKED",
Self::NavExtraArmingSafetyBypassed => "NAV_EXTRA_ARMING_SAFETY_BYPASSED",
Self::NavMotorStopOrIdle => "NAV_MOTOR_STOP_OR_IDLE",
Self::Rover => "ROVER",
Self::SetReversibleMotorsForward => "SET_REVERSIBLE_MOTORS_FORWARD",
Self::SmallAngle => "SMALL_ANGLE",
Self::Tailsitter => "TAILSITTER",
}
}
}
#[allow(unused_qualifications)]
impl ::core::fmt::Display for State {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
let s = <Self as crate::units::Flag>::as_name(self);
f.write_str(s)
}
}
#[allow(
unused_qualifications,
clippy::enum_glob_use,
clippy::match_same_arms,
clippy::unseparated_literal_suffix
)]
impl State {
const fn from_bit(bit: u32, fw: crate::headers::InternalFirmware) -> Option<Self> {
use crate::headers::InternalFirmware::*;
match (bit, fw) {
(
0u32,
Betaflight4_2 | Betaflight4_3 | Betaflight4_4 | Betaflight4_5 | Inav5 | Inav6
| Inav7 | Inav8,
) => Some(Self::GpsFixHome),
(
1u32,
Betaflight4_2 | Betaflight4_3 | Betaflight4_4 | Betaflight4_5 | Inav5 | Inav6
| Inav7 | Inav8,
) => Some(Self::GpsFix),
(2u32, Betaflight4_3 | Betaflight4_4 | Betaflight4_5) => Some(Self::GpsFixEver),
(2u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::CalibrateMag),
(3u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::SmallAngle),
(4u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::FixedWingLegacy),
(5u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::AntiWindup),
(6u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::FlaperonAvailable),
(7u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::NavMotorStopOrIdle),
(8u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::CompassCalibrated),
(9u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::AccelerometerCalibrated),
(10u32, Inav8) => Some(Self::GpsEstimatedFix),
(11u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::NavCruiseBraking),
(12u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::NavCruiseBrakingBoost),
(13u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::NavCruiseBrakingLocked),
(14u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::NavExtraArmingSafetyBypassed),
(15u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::AirMode),
(16u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::EscSensorEnabled),
(17u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::Airplane),
(18u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::Multirotor),
(19u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::Rover),
(20u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::Boat),
(21u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::AltitudeControl),
(22u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::MoveForwardOnly),
(23u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::SetReversibleMotorsForward),
(24u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::FwHeadingUseYaw),
(25u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::AntiWindupDeactivated),
(26u32, Inav5 | Inav6 | Inav7 | Inav8) => Some(Self::LandingDetected),
(27u32, Inav7 | Inav8) => Some(Self::InFlightEmergencyRearm),
(28u32, Inav7 | Inav8) => Some(Self::Tailsitter),
_ => None,
}
}
const fn to_bit(self, fw: crate::headers::InternalFirmware) -> Option<u32> {
use crate::headers::InternalFirmware::*;
match (self, fw) {
(
Self::GpsFixHome,
Betaflight4_2 | Betaflight4_3 | Betaflight4_4 | Betaflight4_5 | Inav5 | Inav6
| Inav7 | Inav8,
) => Some(0u32),
(
Self::GpsFix,
Betaflight4_2 | Betaflight4_3 | Betaflight4_4 | Betaflight4_5 | Inav5 | Inav6
| Inav7 | Inav8,
) => Some(1u32),
(Self::GpsFixEver, Betaflight4_3 | Betaflight4_4 | Betaflight4_5) => Some(2u32),
(Self::CalibrateMag, Inav5 | Inav6 | Inav7 | Inav8) => Some(2u32),
(Self::SmallAngle, Inav5 | Inav6 | Inav7 | Inav8) => Some(3u32),
(Self::FixedWingLegacy, Inav5 | Inav6 | Inav7 | Inav8) => Some(4u32),
(Self::AntiWindup, Inav5 | Inav6 | Inav7 | Inav8) => Some(5u32),
(Self::FlaperonAvailable, Inav5 | Inav6 | Inav7 | Inav8) => Some(6u32),
(Self::NavMotorStopOrIdle, Inav5 | Inav6 | Inav7 | Inav8) => Some(7u32),
(Self::CompassCalibrated, Inav5 | Inav6 | Inav7 | Inav8) => Some(8u32),
(Self::AccelerometerCalibrated, Inav5 | Inav6 | Inav7 | Inav8) => Some(9u32),
(Self::GpsEstimatedFix, Inav8) => Some(10u32),
(Self::NavCruiseBraking, Inav5 | Inav6 | Inav7 | Inav8) => Some(11u32),
(Self::NavCruiseBrakingBoost, Inav5 | Inav6 | Inav7 | Inav8) => Some(12u32),
(Self::NavCruiseBrakingLocked, Inav5 | Inav6 | Inav7 | Inav8) => Some(13u32),
(Self::NavExtraArmingSafetyBypassed, Inav5 | Inav6 | Inav7 | Inav8) => Some(14u32),
(Self::AirMode, Inav5 | Inav6 | Inav7 | Inav8) => Some(15u32),
(Self::EscSensorEnabled, Inav5 | Inav6 | Inav7 | Inav8) => Some(16u32),
(Self::Airplane, Inav5 | Inav6 | Inav7 | Inav8) => Some(17u32),
(Self::Multirotor, Inav5 | Inav6 | Inav7 | Inav8) => Some(18u32),
(Self::Rover, Inav5 | Inav6 | Inav7 | Inav8) => Some(19u32),
(Self::Boat, Inav5 | Inav6 | Inav7 | Inav8) => Some(20u32),
(Self::AltitudeControl, Inav5 | Inav6 | Inav7 | Inav8) => Some(21u32),
(Self::MoveForwardOnly, Inav5 | Inav6 | Inav7 | Inav8) => Some(22u32),
(Self::SetReversibleMotorsForward, Inav5 | Inav6 | Inav7 | Inav8) => Some(23u32),
(Self::FwHeadingUseYaw, Inav5 | Inav6 | Inav7 | Inav8) => Some(24u32),
(Self::AntiWindupDeactivated, Inav5 | Inav6 | Inav7 | Inav8) => Some(25u32),
(Self::LandingDetected, Inav5 | Inav6 | Inav7 | Inav8) => Some(26u32),
(Self::InFlightEmergencyRearm, Inav7 | Inav8) => Some(27u32),
(Self::Tailsitter, Inav7 | Inav8) => Some(28u32),
_ => None,
}
}
}