1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3use spacepackets::ecss::{EcssEnumU16, EcssEnumeration};
4use spacepackets::util::UnsignedEnum;
5use spacepackets::ByteConversionError;
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq)]
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11pub struct ResultU16 {
12 group_id: u8,
13 unique_id: u8,
14}
15
16impl ResultU16 {
17 #[inline]
18 pub const fn new(group_id: u8, unique_id: u8) -> Self {
19 Self {
20 group_id,
21 unique_id,
22 }
23 }
24
25 #[inline]
26 pub const fn raw(&self) -> u16 {
27 ((self.group_id as u16) << 8) | self.unique_id as u16
28 }
29
30 #[inline]
31 pub const fn group_id(&self) -> u8 {
32 self.group_id
33 }
34
35 #[inline]
36 pub const fn unique_id(&self) -> u8 {
37 self.unique_id
38 }
39
40 #[inline]
41 pub fn from_be_bytes(bytes: [u8; 2]) -> Self {
42 Self::from(u16::from_be_bytes(bytes))
43 }
44}
45
46impl From<u16> for ResultU16 {
47 fn from(value: u16) -> Self {
48 Self::new(((value >> 8) & 0xff) as u8, (value & 0xff) as u8)
49 }
50}
51
52impl From<ResultU16> for EcssEnumU16 {
53 fn from(v: ResultU16) -> Self {
54 EcssEnumU16::new(v.raw())
55 }
56}
57
58impl UnsignedEnum for ResultU16 {
59 #[inline]
60 fn size(&self) -> usize {
61 core::mem::size_of::<u16>()
62 }
63
64 fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
65 if buf.len() < 2 {
66 return Err(ByteConversionError::ToSliceTooSmall {
67 found: buf.len(),
68 expected: 2,
69 });
70 }
71 buf[0] = self.group_id;
72 buf[1] = self.unique_id;
73 Ok(self.size())
74 }
75
76 #[inline]
77 fn value_raw(&self) -> u64 {
78 self.raw() as u64
79 }
80}
81
82impl EcssEnumeration for ResultU16 {
83 #[inline]
84 fn pfc(&self) -> u8 {
85 16
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 const RESULT_CODE_CONST: ResultU16 = ResultU16::new(1, 1);
94
95 #[test]
96 pub fn test_basic() {
97 let result_code = ResultU16::new(1, 1);
98 assert_eq!(result_code.unique_id(), 1);
99 assert_eq!(result_code.group_id(), 1);
100 assert_eq!(result_code, RESULT_CODE_CONST);
101 assert_eq!(result_code.raw(), (1_u16 << 8) | 1);
102 assert_eq!(result_code.pfc(), 16);
103 assert_eq!(result_code.size(), 2);
104 let mut buf: [u8; 2] = [0; 2];
105 let written = result_code.write_to_be_bytes(&mut buf).unwrap();
106 assert_eq!(written, 2);
107 assert_eq!(buf[0], 1);
108 assert_eq!(buf[1], 1);
109 let read_back = ResultU16::from_be_bytes(buf);
110 assert_eq!(read_back, result_code);
111 }
112
113 #[test]
114 fn test_from_u16() {
115 let result_code = ResultU16::new(1, 1);
116 let result_code_2 = ResultU16::from(result_code.raw());
117 assert_eq!(result_code, result_code_2);
118 }
119}