use crate::ardrone3::ArDrone3;
use crate::common;
use crate::jumping_sumo;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Feature {
Common(common::Class),
ArDrone3(ArDrone3),
Minidrone,
JumpingSumo(jumping_sumo::Class),
SkyController,
PowerUp,
Generic,
FollowMe,
Wifi,
RC,
DroneManager,
Mapper,
Debug,
ControllerInfo,
MapperMini,
ThermalCam,
Animation,
SequoiaCam,
}
impl Into<u8> for Feature {
fn into(self) -> u8 {
match self {
Self::Common(_) => 0,
Self::ArDrone3(_) => 1,
Self::Minidrone => 2,
Self::JumpingSumo(_) => 3,
Self::SkyController => 4,
Self::PowerUp => 8,
Self::Generic => 133,
Self::FollowMe => 134,
Self::Wifi => 135,
Self::RC => 136,
Self::DroneManager => 137,
Self::Mapper => 138,
Self::Debug => 139,
Self::ControllerInfo => 140,
Self::MapperMini => 141,
Self::ThermalCam => 142,
Self::Animation => 144,
Self::SequoiaCam => 147,
}
}
}
pub mod scroll_impl {
use super::*;
use crate::MessageError;
use scroll::{ctx, Endian, Pread, Pwrite};
impl<'a> ctx::TryFromCtx<'a, Endian> for Feature {
type Error = MessageError;
fn try_from_ctx(src: &'a [u8], endian: Endian) -> Result<(Self, usize), Self::Error> {
let mut offset = 0;
let feature = match src.gread_with::<u8>(&mut offset, endian)? {
0 => {
let common = src.gread_with(&mut offset, endian)?;
Self::Common(common)
}
1 => {
let ardrone3 = src.gread_with(&mut offset, endian)?;
Self::ArDrone3(ardrone3)
}
2 => Self::Minidrone,
3 => {
let js_class = src.gread_with(&mut offset, endian)?;
Feature::JumpingSumo(js_class)
}
4 => Self::SkyController,
8 => Self::PowerUp,
133 => Self::Generic,
134 => Self::FollowMe,
135 => Self::Wifi,
136 => Self::RC,
137 => Self::DroneManager,
138 => Self::Mapper,
139 => Self::Debug,
140 => Self::ControllerInfo,
141 => Self::MapperMini,
142 => Self::ThermalCam,
144 => Self::Animation,
147 => Self::SequoiaCam,
value => {
return Err(Self::Error::OutOfBound {
value: value.into(),
param: "Feature".to_string(),
})
}
};
Ok((feature, offset))
}
}
impl<'a> ctx::TryIntoCtx<Endian> for Feature {
type Error = MessageError;
fn try_into_ctx(self, this: &mut [u8], ctx: Endian) -> Result<usize, Self::Error> {
let mut offset = 0;
this.gwrite_with::<u8>(self.into(), &mut offset, ctx)?;
match self {
Self::Common(common) => {
this.gwrite_with(common, &mut offset, ctx)?;
}
Self::ArDrone3(ardrone3) => {
this.gwrite_with(ardrone3, &mut offset, ctx)?;
}
Self::JumpingSumo(js) => {
this.gwrite_with(js, &mut offset, ctx)?;
}
_ => unimplemented!("Not all Features are impled"),
}
Ok(offset)
}
}
}
#[cfg(test)]
mod command_tests {
use super::*;
#[test]
fn test_feature() {
assert_feature(
Feature::Common(common::Class::Common(common::Common::AllStates)),
0,
);
assert_feature(Feature::ArDrone3(ArDrone3::TakeOff), 1);
assert_feature(Feature::Minidrone, 2);
assert_feature(
Feature::JumpingSumo(jumping_sumo::Class::Piloting(
jumping_sumo::PilotingID::Pilot(jumping_sumo::PilotState::default()),
)),
3,
);
assert_feature(Feature::SkyController, 4);
assert_feature(Feature::PowerUp, 8);
assert_feature(Feature::Generic, 133);
assert_feature(Feature::FollowMe, 134);
assert_feature(Feature::Wifi, 135);
assert_feature(Feature::RC, 136);
assert_feature(Feature::DroneManager, 137);
assert_feature(Feature::Mapper, 138);
assert_feature(Feature::Debug, 139);
assert_feature(Feature::ControllerInfo, 140);
assert_feature(Feature::MapperMini, 141);
assert_feature(Feature::ThermalCam, 142);
assert_feature(Feature::Animation, 144);
assert_feature(Feature::SequoiaCam, 147);
}
fn assert_feature(f: Feature, v: u8) {
let as_u8: u8 = f.into();
assert_eq!(v, as_u8);
}
}