1use crate::tmtc::TargetId;
2use core::mem::size_of;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use spacepackets::ByteConversionError;
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq)]
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9pub struct ModeAndSubmode {
10    mode: u32,
11    submode: u16,
12}
13
14impl ModeAndSubmode {
15    pub const fn new_mode_only(mode: u32) -> Self {
16        Self { mode, submode: 0 }
17    }
18
19    pub const fn new(mode: u32, submode: u16) -> Self {
20        Self { mode, submode }
21    }
22
23    pub fn raw_len() -> usize {
24        size_of::<u32>() + size_of::<u16>()
25    }
26
27    pub fn from_be_bytes(buf: &[u8]) -> Result<Self, ByteConversionError> {
28        if buf.len() < 6 {
29            return Err(ByteConversionError::FromSliceTooSmall {
30                expected: 6,
31                found: buf.len(),
32            });
33        }
34        Ok(Self {
35            mode: u32::from_be_bytes(buf[0..4].try_into().unwrap()),
36            submode: u16::from_be_bytes(buf[4..6].try_into().unwrap()),
37        })
38    }
39
40    pub fn mode(&self) -> u32 {
41        self.mode
42    }
43
44    pub fn submode(&self) -> u16 {
45        self.submode
46    }
47}
48#[derive(Debug, Copy, Clone, PartialEq, Eq)]
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50pub struct ModeCommand {
51    pub address: TargetId,
52    pub mode_submode: ModeAndSubmode,
53}
54
55impl ModeCommand {
56    pub const fn new(address: TargetId, mode_submode: ModeAndSubmode) -> Self {
57        Self {
58            address,
59            mode_submode,
60        }
61    }
62
63    pub fn address(&self) -> TargetId {
64        self.address
65    }
66
67    pub fn mode_submode(&self) -> ModeAndSubmode {
68        self.mode_submode
69    }
70
71    pub fn mode(&self) -> u32 {
72        self.mode_submode.mode
73    }
74
75    pub fn submode(&self) -> u16 {
76        self.mode_submode.submode
77    }
78}
79
80#[derive(Debug, Copy, Clone, PartialEq, Eq)]
81#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
82pub enum ModeRequest {
83    SetMode(ModeAndSubmode),
84    ReadMode,
85    AnnounceMode,
86    AnnounceModeRecursive,
87}
88
89#[derive(Debug, Copy, Clone, PartialEq, Eq)]
90#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
91pub struct TargetedModeRequest {
92    target_id: TargetId,
93    mode_request: ModeRequest,
94}