use num_enum::IntoPrimitive;
use num_enum::TryFromPrimitive;
use std::convert::TryFrom;
use crate::protocol::{*};
use crate::communication::extractor::Extractor;
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub enum CommandType {
#[num_enum(default)]
None = 0x00,
Stop = 0x01,
ModeControlFlight = 0x02, Headless = 0x03, ControlSpeed = 0x04,
ClearBias = 0x05, ClearTrim = 0x06,
FlightEvent = 0x07,
SetDefault = 0x08, Backlight = 0x09, ModeController = 0x0A, Link = 0x0B, ClearMagnetometer = 0x0C,
ClearCounter = 0xA0, JumpToBootloader = 0xA1, JumpToApplication = 0xA2,
NavigationTargetClear = 0xE0, NavigationStart = 0xE1, NavigationPause = 0xE2, NavigationRestart = 0xE3, NavigationStop = 0xE4, NavigationNext = 0xE5, NavigationReturnToHome = 0xE6,
GpsRtkBase = 0xEA,
GpsRtkRover = 0xEB,
TestLock = 0xF0, }
impl CommandType {
pub fn from_u8(data_u8: u8) -> CommandType {
match CommandType::try_from( data_u8 ) {
Ok(data) => { data },
_ => { CommandType::None },
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct Command {
pub command_type: CommandType,
pub option: u8,
}
impl Command {
pub fn new() -> Command{
Command {
command_type: CommandType::None,
option: 0,
}
}
pub const fn size() -> usize { 2 }
pub fn parse(slice_data: &[u8]) -> Result<Command, &'static str> {
if slice_data.len() == Command::size() {
let mut ext: Extractor = Extractor::from_slice(slice_data);
Ok(Command{
command_type: CommandType::from_u8(ext.get_u8()),
option: ext.get_u8(),
})
}
else { Err("Wrong length") }
}
}
impl Serializable for Command {
fn to_vec(&self) -> Vec<u8> {
let mut vec_data : Vec<u8> = Vec::new();
vec_data.push(self.command_type.into());
vec_data.extend_from_slice(&self.option.to_le_bytes());
vec_data
}
}
#[derive(Debug, Copy, Clone)]
pub struct CommandLightEvent {
pub command: Command,
pub light_event: light::Event,
}
impl CommandLightEvent {
pub fn new() -> CommandLightEvent{
CommandLightEvent {
command: Command::new(),
light_event: light::Event::new(),
}
}
pub const fn size() -> usize { 5 }
pub fn parse(slice_data: &[u8]) -> Result<CommandLightEvent, &'static str> {
if slice_data.len() == CommandLightEvent::size() {
let mut ext: Extractor = Extractor::from_slice(slice_data);
Ok(CommandLightEvent{
command: Command{
command_type: CommandType::from_u8(ext.get_u8()),
option: ext.get_u8(),
},
light_event: light::Event{
event: ext.get_u8(),
interval: ext.get_u16(),
repeat: ext.get_u8(),
}
})
}
else { Err("Wrong length") }
}
}
impl Serializable for CommandLightEvent {
fn to_vec(&self) -> Vec<u8> {
let mut vec_data : Vec<u8> = Vec::new();
vec_data.push(self.command.command_type.into());
vec_data.extend_from_slice(&self.command.option.to_le_bytes());
vec_data.extend_from_slice(&self.light_event.event.to_le_bytes());
vec_data.extend_from_slice(&self.light_event.interval.to_le_bytes());
vec_data.extend_from_slice(&self.light_event.repeat.to_le_bytes());
vec_data
}
}
#[derive(Debug, Copy, Clone)]
pub struct CommandLightEventColor {
pub command: Command,
pub event: light::Event,
pub color: light::Color,
}
impl CommandLightEventColor {
pub fn new() -> CommandLightEventColor{
CommandLightEventColor {
command: Command::new(),
event: light::Event::new(),
color: light::Color::new(),
}
}
pub const fn size() -> usize { 7 }
pub fn parse(slice_data: &[u8]) -> Result<CommandLightEventColor, &'static str> {
if slice_data.len() == CommandLightEventColor::size() {
let mut ext: Extractor = Extractor::from_slice(slice_data);
Ok( CommandLightEventColor{
command: Command{
command_type: CommandType::from_u8(ext.get_u8()),
option: ext.get_u8(),
},
event: light::Event {
event: ext.get_u8(),
interval: ext.get_u16(),
repeat: ext.get_u8(),
},
color: light::Color {
r: ext.get_u8(),
g: ext.get_u8(),
b: ext.get_u8(),
},
})
}
else { Err("Wrong length") }
}
}
impl Serializable for CommandLightEventColor {
fn to_vec(&self) -> Vec<u8> {
let mut vec_data : Vec<u8> = Vec::new();
vec_data.extend_from_slice(&self.event.event.to_le_bytes());
vec_data.extend_from_slice(&self.event.interval.to_le_bytes());
vec_data.extend_from_slice(&self.event.repeat.to_le_bytes());
vec_data.extend_from_slice(&self.color.r.to_le_bytes());
vec_data.extend_from_slice(&self.color.g.to_le_bytes());
vec_data.extend_from_slice(&self.color.b.to_le_bytes());
vec_data
}
}