satrs_core/
params.rs

1//! Parameter types and enums.
2//!
3//! This module contains various helper types.
4//!
5//! # Primtive Parameter Wrappers and Enumeration
6//!
7//! This module includes wrapper for primitive rust types using the newtype pattern.
8//! This was also done for pairs and triplets of these primitive types.
9//! The [WritableToBeBytes] was implemented for all those types as well, which allows to easily
10//! convert them into a network friendly raw byte format. The [ParamsRaw] enumeration groups
11//! all newtypes and implements the [WritableToBeBytes] trait itself.
12//!
13//! ## Example for primitive type wrapper
14//!
15//! ```
16//! use satrs_core::params::{ParamsRaw, ToBeBytes, U32Pair, WritableToBeBytes};
17//!
18//! let u32_pair = U32Pair(0x1010, 25);
19//! assert_eq!(u32_pair.0, 0x1010);
20//! assert_eq!(u32_pair.1, 25);
21//! // Convert to raw stream
22//! let raw_buf = u32_pair.to_be_bytes();
23//! assert_eq!(raw_buf, [0, 0, 0x10, 0x10, 0, 0, 0, 25]);
24//!
25//! // Convert to enum variant
26//! let params_raw: ParamsRaw = u32_pair.into();
27//! assert_eq!(params_raw, (0x1010_u32, 25_u32).into());
28//!
29//! // Convert to stream using the enum variant
30//! let mut other_raw_buf: [u8; 8] = [0; 8];
31//! params_raw.write_to_be_bytes(&mut other_raw_buf).expect("Writing parameter to buffer failed");
32//! assert_eq!(other_raw_buf, [0, 0, 0x10, 0x10, 0, 0, 0, 25]);
33//!
34//! // Create a pair from a raw stream
35//! let u32_pair_from_stream: U32Pair = raw_buf.as_slice().try_into().unwrap();
36//! assert_eq!(u32_pair_from_stream.0, 0x1010);
37//! assert_eq!(u32_pair_from_stream.1, 25);
38//! ```
39//!
40//! # Generic Parameter Enumeration
41//!
42//! The module also contains generic parameter enumerations.
43//! This includes the [ParamsHeapless] enumeration for contained values which do not require heap
44//! allocation, and the [Params] which enumerates [ParamsHeapless] and some additional types which
45//! require [alloc] support but allow for more flexbility.
46#[cfg(feature = "alloc")]
47use crate::pool::StoreAddr;
48#[cfg(feature = "alloc")]
49use alloc::string::{String, ToString};
50#[cfg(feature = "alloc")]
51use alloc::vec::Vec;
52use core::fmt::Debug;
53use core::mem::size_of;
54use paste::paste;
55use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU64, EcssEnumU8};
56use spacepackets::util::UnsignedEnum;
57use spacepackets::ByteConversionError;
58
59#[cfg(feature = "alloc")]
60pub use alloc_mod::*;
61pub use spacepackets::util::ToBeBytes;
62
63/// Generic trait which is used for objects which can be converted into a raw network (big) endian
64/// byte format.
65pub trait WritableToBeBytes {
66    fn raw_len(&self) -> usize;
67    /// Writes the object to a raw buffer in network endianness (big)
68    fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError>;
69}
70
71macro_rules! param_to_be_bytes_impl {
72    ($Newtype: ident) => {
73        impl WritableToBeBytes for $Newtype {
74            #[inline]
75            fn raw_len(&self) -> usize {
76                size_of::<<Self as ToBeBytes>::ByteArray>()
77            }
78
79            fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
80                let raw_len = self.raw_len();
81                if buf.len() < raw_len {
82                    return Err(ByteConversionError::ToSliceTooSmall {
83                        found: buf.len(),
84                        expected: raw_len,
85                    });
86                }
87                buf[0..raw_len].copy_from_slice(&self.to_be_bytes());
88                Ok(raw_len)
89            }
90        }
91    };
92}
93
94macro_rules! primitive_newtypes_with_eq {
95    ($($ty: ty,)+) => {
96        $(
97            paste! {
98                #[derive(Debug, Copy, Clone, PartialEq, Eq)]
99                pub struct [<$ty:upper>](pub $ty);
100                #[derive(Debug, Copy, Clone, PartialEq, Eq)]
101                pub struct [<$ty:upper Pair>](pub $ty, pub $ty);
102                #[derive(Debug, Copy, Clone, PartialEq, Eq)]
103                pub struct [<$ty:upper Triplet>](pub $ty, pub $ty, pub $ty);
104
105                param_to_be_bytes_impl!([<$ty:upper>]);
106                param_to_be_bytes_impl!([<$ty:upper Pair>]);
107                param_to_be_bytes_impl!([<$ty:upper Triplet>]);
108
109                impl From<$ty> for [<$ty:upper>] {
110                    fn from(v: $ty) -> Self {
111                        Self(v)
112                    }
113                }
114                impl From<($ty, $ty)> for [<$ty:upper Pair>] {
115                    fn from(v: ($ty, $ty)) -> Self {
116                        Self(v.0, v.1)
117                    }
118                }
119                impl From<($ty, $ty, $ty)> for [<$ty:upper Triplet>] {
120                    fn from(v: ($ty, $ty, $ty)) -> Self {
121                        Self(v.0, v.1, v.2)
122                    }
123                }
124            }
125        )+
126    }
127}
128
129macro_rules! primitive_newtypes {
130    ($($ty: ty,)+) => {
131        $(
132            paste! {
133                #[derive(Debug, Copy, Clone, PartialEq)]
134                pub struct [<$ty:upper>](pub $ty);
135                #[derive(Debug, Copy, Clone, PartialEq)]
136                pub struct [<$ty:upper Pair>](pub $ty, pub $ty);
137                #[derive(Debug, Copy, Clone, PartialEq)]
138                pub struct [<$ty:upper Triplet>](pub $ty, pub $ty, pub $ty);
139
140                param_to_be_bytes_impl!([<$ty:upper>]);
141                param_to_be_bytes_impl!([<$ty:upper Pair>]);
142                param_to_be_bytes_impl!([<$ty:upper Triplet>]);
143
144                impl From<$ty> for [<$ty:upper>] {
145                    fn from(v: $ty) -> Self {
146                        Self(v)
147                    }
148                }
149                impl From<($ty, $ty)> for [<$ty:upper Pair>] {
150                    fn from(v: ($ty, $ty)) -> Self {
151                        Self(v.0, v.1)
152                    }
153                }
154                impl From<($ty, $ty, $ty)> for [<$ty:upper Triplet>] {
155                    fn from(v: ($ty, $ty, $ty)) -> Self {
156                        Self(v.0, v.1, v.2)
157                    }
158                }
159            }
160        )+
161    }
162}
163
164primitive_newtypes_with_eq!(u8, u16, u32, u64, i8, i16, i32, i64,);
165primitive_newtypes!(f32, f64,);
166
167macro_rules! scalar_byte_conversions_impl {
168    ($($ty: ty,)+) => {
169        $(
170            paste! {
171                impl ToBeBytes for [<$ty:upper>] {
172                    type ByteArray = [u8; size_of::<$ty>()];
173
174                    fn written_len(&self) -> usize {
175                        size_of::<Self::ByteArray>()
176                    }
177
178                    fn to_be_bytes(&self) -> Self::ByteArray {
179                        self.0.to_be_bytes()
180                    }
181                }
182
183                impl TryFrom<&[u8]> for [<$ty:upper>] {
184                    type Error = ByteConversionError;
185
186                    fn try_from(v: &[u8]) -> Result<Self, Self::Error>  {
187                        if v.len() < size_of::<$ty>() {
188                            return Err(ByteConversionError::FromSliceTooSmall{
189                                expected: size_of::<$ty>(),
190                                found: v.len()
191                            });
192                        }
193                        Ok([<$ty:upper>]($ty::from_be_bytes(v[0..size_of::<$ty>()].try_into().unwrap())))
194                    }
195                }
196            }
197        )+
198    }
199}
200
201macro_rules! pair_byte_conversions_impl {
202    ($($ty: ty,)+) => {
203        $(
204            paste! {
205                impl ToBeBytes for [<$ty:upper Pair>] {
206                    type ByteArray = [u8; size_of::<$ty>() * 2];
207
208                    fn written_len(&self) -> usize {
209                        size_of::<Self::ByteArray>()
210                    }
211
212                    fn to_be_bytes(&self) -> Self::ByteArray {
213                        let mut array = [0; size_of::<$ty>() * 2];
214                        array[0..size_of::<$ty>()].copy_from_slice(&self.0.to_be_bytes());
215                        array[
216                            size_of::<$ty>()..2 * size_of::<$ty>()
217                        ].copy_from_slice(&self.1.to_be_bytes());
218                        array
219                    }
220                }
221
222                impl TryFrom<&[u8]> for [<$ty:upper Pair>] {
223                    type Error = ByteConversionError;
224
225                    fn try_from(v: &[u8]) -> Result<Self, Self::Error>  {
226                        if v.len() < 2 * size_of::<$ty>() {
227                            return Err(ByteConversionError::FromSliceTooSmall{
228                                expected: 2 * size_of::<$ty>(),
229                                found: v.len()
230                            });
231                        }
232                        Ok([<$ty:upper Pair>](
233                            $ty::from_be_bytes(v[0..size_of::<$ty>()].try_into().unwrap()),
234                            $ty::from_be_bytes(v[size_of::<$ty>()..2 * size_of::<$ty>()].try_into().unwrap())
235                        ))
236                    }
237                }
238            }
239        )+
240    }
241}
242
243macro_rules! triplet_to_be_bytes_impl {
244    ($($ty: ty,)+) => {
245        $(
246            paste! {
247                impl ToBeBytes for [<$ty:upper Triplet>] {
248                    type ByteArray = [u8; size_of::<$ty>() * 3];
249
250                    fn written_len(&self) -> usize {
251                        size_of::<Self::ByteArray>()
252                    }
253
254                    fn to_be_bytes(&self) -> Self::ByteArray {
255                        let mut array = [0; size_of::<$ty>() * 3];
256                        array[0..size_of::<$ty>()].copy_from_slice(&self.0.to_be_bytes());
257                        array[
258                            size_of::<$ty>()..2 * size_of::<$ty>()
259                        ].copy_from_slice(&self.1.to_be_bytes());
260                        array[
261                            2 * size_of::<$ty>()..3 * size_of::<$ty>()
262                        ].copy_from_slice(&self.2.to_be_bytes());
263                        array
264                    }
265                }
266                impl TryFrom<&[u8]> for [<$ty:upper Triplet>] {
267                    type Error = ByteConversionError;
268
269                    fn try_from(v: &[u8]) -> Result<Self, Self::Error>  {
270                        if v.len() < 3 * size_of::<$ty>() {
271                            return Err(ByteConversionError::FromSliceTooSmall{
272                                expected: 3 * size_of::<$ty>(),
273                                found: v.len()
274                            });
275                        }
276                        Ok([<$ty:upper Triplet>](
277                            $ty::from_be_bytes(v[0..size_of::<$ty>()].try_into().unwrap()),
278                            $ty::from_be_bytes(v[size_of::<$ty>()..2 * size_of::<$ty>()].try_into().unwrap()),
279                            $ty::from_be_bytes(v[2 * size_of::<$ty>()..3 * size_of::<$ty>()].try_into().unwrap())
280                        ))
281                    }
282                }
283            }
284        )+
285    }
286}
287
288scalar_byte_conversions_impl!(u8, u16, u32, u64, i8, i16, i32, i64, f32, f64,);
289
290impl ToBeBytes for U8Pair {
291    type ByteArray = [u8; 2];
292
293    fn written_len(&self) -> usize {
294        size_of::<Self::ByteArray>()
295    }
296
297    fn to_be_bytes(&self) -> Self::ByteArray {
298        let mut array = [0; 2];
299        array[0] = self.0;
300        array[1] = self.1;
301        array
302    }
303}
304
305impl ToBeBytes for I8Pair {
306    type ByteArray = [u8; 2];
307
308    fn written_len(&self) -> usize {
309        size_of::<Self::ByteArray>()
310    }
311
312    fn to_be_bytes(&self) -> Self::ByteArray {
313        let mut array = [0; 2];
314        array[0] = self.0 as u8;
315        array[1] = self.1 as u8;
316        array
317    }
318}
319
320impl ToBeBytes for U8Triplet {
321    type ByteArray = [u8; 3];
322
323    fn written_len(&self) -> usize {
324        size_of::<Self::ByteArray>()
325    }
326
327    fn to_be_bytes(&self) -> Self::ByteArray {
328        let mut array = [0; 3];
329        array[0] = self.0;
330        array[1] = self.1;
331        array[2] = self.2;
332        array
333    }
334}
335
336impl ToBeBytes for I8Triplet {
337    type ByteArray = [u8; 3];
338
339    fn written_len(&self) -> usize {
340        size_of::<Self::ByteArray>()
341    }
342
343    fn to_be_bytes(&self) -> Self::ByteArray {
344        let mut array = [0; 3];
345        array[0] = self.0 as u8;
346        array[1] = self.1 as u8;
347        array[2] = self.2 as u8;
348        array
349    }
350}
351
352pair_byte_conversions_impl!(u16, u32, u64, i16, i32, i64, f32, f64,);
353triplet_to_be_bytes_impl!(u16, u32, u64, i16, i32, i64, f32, f64,);
354
355/// Generic enumeration for additonal parameters only consisting of primitive data types.
356///
357/// All contained variants and the enum itself implement the [WritableToBeBytes] trait, which
358/// allows to easily convert them into a network-friendly format.
359#[derive(Debug, Copy, Clone, PartialEq)]
360pub enum ParamsRaw {
361    U8(U8),
362    U8Pair(U8Pair),
363    U8Triplet(U8Triplet),
364    I8(I8),
365    I8Pair(I8Pair),
366    I8Triplet(I8Triplet),
367    U16(U16),
368    U16Pair(U16Pair),
369    U16Triplet(U16Triplet),
370    I16(I16),
371    I16Pair(I16Pair),
372    I16Triplet(I16Triplet),
373    U32(U32),
374    U32Pair(U32Pair),
375    U32Triplet(U32Triplet),
376    I32(I32),
377    I32Pair(I32Pair),
378    I32Triplet(I32Triplet),
379    F32(F32),
380    F32Pair(F32Pair),
381    F32Triplet(F32Triplet),
382    U64(U64),
383    I64(I64),
384    F64(F64),
385}
386
387impl WritableToBeBytes for ParamsRaw {
388    fn raw_len(&self) -> usize {
389        match self {
390            ParamsRaw::U8(v) => v.raw_len(),
391            ParamsRaw::U8Pair(v) => v.raw_len(),
392            ParamsRaw::U8Triplet(v) => v.raw_len(),
393            ParamsRaw::I8(v) => v.raw_len(),
394            ParamsRaw::I8Pair(v) => v.raw_len(),
395            ParamsRaw::I8Triplet(v) => v.raw_len(),
396            ParamsRaw::U16(v) => v.raw_len(),
397            ParamsRaw::U16Pair(v) => v.raw_len(),
398            ParamsRaw::U16Triplet(v) => v.raw_len(),
399            ParamsRaw::I16(v) => v.raw_len(),
400            ParamsRaw::I16Pair(v) => v.raw_len(),
401            ParamsRaw::I16Triplet(v) => v.raw_len(),
402            ParamsRaw::U32(v) => v.raw_len(),
403            ParamsRaw::U32Pair(v) => v.raw_len(),
404            ParamsRaw::U32Triplet(v) => v.raw_len(),
405            ParamsRaw::I32(v) => v.raw_len(),
406            ParamsRaw::I32Pair(v) => v.raw_len(),
407            ParamsRaw::I32Triplet(v) => v.raw_len(),
408            ParamsRaw::F32(v) => v.raw_len(),
409            ParamsRaw::F32Pair(v) => v.raw_len(),
410            ParamsRaw::F32Triplet(v) => v.raw_len(),
411            ParamsRaw::U64(v) => v.raw_len(),
412            ParamsRaw::I64(v) => v.raw_len(),
413            ParamsRaw::F64(v) => v.raw_len(),
414        }
415    }
416
417    fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
418        match self {
419            ParamsRaw::U8(v) => v.write_to_be_bytes(buf),
420            ParamsRaw::U8Pair(v) => v.write_to_be_bytes(buf),
421            ParamsRaw::U8Triplet(v) => v.write_to_be_bytes(buf),
422            ParamsRaw::I8(v) => v.write_to_be_bytes(buf),
423            ParamsRaw::I8Pair(v) => v.write_to_be_bytes(buf),
424            ParamsRaw::I8Triplet(v) => v.write_to_be_bytes(buf),
425            ParamsRaw::U16(v) => v.write_to_be_bytes(buf),
426            ParamsRaw::U16Pair(v) => v.write_to_be_bytes(buf),
427            ParamsRaw::U16Triplet(v) => v.write_to_be_bytes(buf),
428            ParamsRaw::I16(v) => v.write_to_be_bytes(buf),
429            ParamsRaw::I16Pair(v) => v.write_to_be_bytes(buf),
430            ParamsRaw::I16Triplet(v) => v.write_to_be_bytes(buf),
431            ParamsRaw::U32(v) => v.write_to_be_bytes(buf),
432            ParamsRaw::U32Pair(v) => v.write_to_be_bytes(buf),
433            ParamsRaw::U32Triplet(v) => v.write_to_be_bytes(buf),
434            ParamsRaw::I32(v) => v.write_to_be_bytes(buf),
435            ParamsRaw::I32Pair(v) => v.write_to_be_bytes(buf),
436            ParamsRaw::I32Triplet(v) => v.write_to_be_bytes(buf),
437            ParamsRaw::F32(v) => v.write_to_be_bytes(buf),
438            ParamsRaw::F32Pair(v) => v.write_to_be_bytes(buf),
439            ParamsRaw::F32Triplet(v) => v.write_to_be_bytes(buf),
440            ParamsRaw::U64(v) => v.write_to_be_bytes(buf),
441            ParamsRaw::I64(v) => v.write_to_be_bytes(buf),
442            ParamsRaw::F64(v) => v.write_to_be_bytes(buf),
443        }
444    }
445}
446
447macro_rules! params_raw_from_newtype {
448    ($($newtype: ident,)+) => {
449        $(
450            impl From<$newtype> for ParamsRaw {
451                fn from(v: $newtype) -> Self {
452                    Self::$newtype(v)
453                }
454            }
455        )+
456    }
457}
458
459params_raw_from_newtype!(
460    U8, U8Pair, U8Triplet, U16, U16Pair, U16Triplet, U32, U32Pair, U32Triplet, I8, I8Pair,
461    I8Triplet, I16, I16Pair, I16Triplet, I32, I32Pair, I32Triplet, F32, F32Pair, F32Triplet, U64,
462    I64, F64,
463);
464
465#[derive(Debug, Copy, Clone, PartialEq, Eq)]
466pub enum EcssEnumParams {
467    U8(EcssEnumU8),
468    U16(EcssEnumU16),
469    U32(EcssEnumU32),
470    U64(EcssEnumU64),
471}
472
473macro_rules! writable_as_be_bytes_ecss_enum_impl {
474    ($EnumIdent: ident) => {
475        impl WritableToBeBytes for $EnumIdent {
476            fn raw_len(&self) -> usize {
477                self.size()
478            }
479
480            fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
481                <Self as UnsignedEnum>::write_to_be_bytes(self, buf).map(|_| self.raw_len())
482            }
483        }
484    };
485}
486
487writable_as_be_bytes_ecss_enum_impl!(EcssEnumU8);
488writable_as_be_bytes_ecss_enum_impl!(EcssEnumU16);
489writable_as_be_bytes_ecss_enum_impl!(EcssEnumU32);
490writable_as_be_bytes_ecss_enum_impl!(EcssEnumU64);
491
492impl WritableToBeBytes for EcssEnumParams {
493    fn raw_len(&self) -> usize {
494        match self {
495            EcssEnumParams::U8(e) => e.raw_len(),
496            EcssEnumParams::U16(e) => e.raw_len(),
497            EcssEnumParams::U32(e) => e.raw_len(),
498            EcssEnumParams::U64(e) => e.raw_len(),
499        }
500    }
501
502    fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
503        match self {
504            EcssEnumParams::U8(e) => WritableToBeBytes::write_to_be_bytes(e, buf),
505            EcssEnumParams::U16(e) => WritableToBeBytes::write_to_be_bytes(e, buf),
506            EcssEnumParams::U32(e) => WritableToBeBytes::write_to_be_bytes(e, buf),
507            EcssEnumParams::U64(e) => WritableToBeBytes::write_to_be_bytes(e, buf),
508        }
509    }
510}
511
512/// Generic enumeration for parameters which do not rely on heap allocations.
513#[derive(Debug, Copy, Clone, PartialEq)]
514pub enum ParamsHeapless {
515    Raw(ParamsRaw),
516    EcssEnum(EcssEnumParams),
517}
518
519macro_rules! from_conversions_for_raw {
520    ($(($raw_ty: ty, $TargetPath: path),)+) => {
521        $(
522            impl From<$raw_ty> for ParamsRaw {
523                fn from(val: $raw_ty) -> Self {
524                    $TargetPath(val.into())
525                }
526            }
527
528            impl From<$raw_ty> for ParamsHeapless {
529                fn from(val: $raw_ty) -> Self {
530                    ParamsHeapless::Raw(val.into())
531                }
532            }
533        )+
534    };
535}
536
537from_conversions_for_raw!(
538    (u8, Self::U8),
539    ((u8, u8), Self::U8Pair),
540    ((u8, u8, u8), Self::U8Triplet),
541    (i8, Self::I8),
542    ((i8, i8), Self::I8Pair),
543    ((i8, i8, i8), Self::I8Triplet),
544    (u16, Self::U16),
545    ((u16, u16), Self::U16Pair),
546    ((u16, u16, u16), Self::U16Triplet),
547    (i16, Self::I16),
548    ((i16, i16), Self::I16Pair),
549    ((i16, i16, i16), Self::I16Triplet),
550    (u32, Self::U32),
551    ((u32, u32), Self::U32Pair),
552    ((u32, u32, u32), Self::U32Triplet),
553    (i32, Self::I32),
554    ((i32, i32), Self::I32Pair),
555    ((i32, i32, i32), Self::I32Triplet),
556    (f32, Self::F32),
557    ((f32, f32), Self::F32Pair),
558    ((f32, f32, f32), Self::F32Triplet),
559    (u64, Self::U64),
560    (f64, Self::F64),
561);
562
563#[cfg(feature = "alloc")]
564mod alloc_mod {
565    use super::*;
566    /// Generic enumeration for additional parameters, including parameters which rely on heap
567    /// allocations.
568    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
569    #[derive(Debug, Clone)]
570    pub enum Params {
571        Heapless(ParamsHeapless),
572        Store(StoreAddr),
573        Vec(Vec<u8>),
574        String(String),
575    }
576
577    impl From<StoreAddr> for Params {
578        fn from(x: StoreAddr) -> Self {
579            Self::Store(x)
580        }
581    }
582
583    impl From<ParamsHeapless> for Params {
584        fn from(x: ParamsHeapless) -> Self {
585            Self::Heapless(x)
586        }
587    }
588
589    impl From<Vec<u8>> for Params {
590        fn from(val: Vec<u8>) -> Self {
591            Self::Vec(val)
592        }
593    }
594
595    /// Converts a byte slice into the [Params::Vec] variant
596    impl From<&[u8]> for Params {
597        fn from(val: &[u8]) -> Self {
598            Self::Vec(val.to_vec())
599        }
600    }
601
602    impl From<String> for Params {
603        fn from(val: String) -> Self {
604            Self::String(val)
605        }
606    }
607
608    /// Converts a string slice into the [Params::String] variant
609    impl From<&str> for Params {
610        fn from(val: &str) -> Self {
611            Self::String(val.to_string())
612        }
613    }
614}
615
616#[cfg(test)]
617mod tests {
618    use super::*;
619
620    #[test]
621    fn test_basic_u32_pair() {
622        let u32_pair = U32Pair(4, 8);
623        assert_eq!(u32_pair.0, 4);
624        assert_eq!(u32_pair.1, 8);
625        let raw = u32_pair.to_be_bytes();
626        let mut u32_conv_back = u32::from_be_bytes(raw[0..4].try_into().unwrap());
627        assert_eq!(u32_conv_back, 4);
628        u32_conv_back = u32::from_be_bytes(raw[4..8].try_into().unwrap());
629        assert_eq!(u32_conv_back, 8);
630    }
631
632    #[test]
633    fn basic_signed_test_pair() {
634        let i8_pair = I8Pair(-3, -16);
635        assert_eq!(i8_pair.0, -3);
636        assert_eq!(i8_pair.1, -16);
637        let raw = i8_pair.to_be_bytes();
638        let mut i8_conv_back = i8::from_be_bytes(raw[0..1].try_into().unwrap());
639        assert_eq!(i8_conv_back, -3);
640        i8_conv_back = i8::from_be_bytes(raw[1..2].try_into().unwrap());
641        assert_eq!(i8_conv_back, -16);
642    }
643
644    #[test]
645    fn basic_signed_test_triplet() {
646        let i8_triplet = I8Triplet(-3, -16, -126);
647        assert_eq!(i8_triplet.0, -3);
648        assert_eq!(i8_triplet.1, -16);
649        assert_eq!(i8_triplet.2, -126);
650        let raw = i8_triplet.to_be_bytes();
651        let mut i8_conv_back = i8::from_be_bytes(raw[0..1].try_into().unwrap());
652        assert_eq!(i8_conv_back, -3);
653        i8_conv_back = i8::from_be_bytes(raw[1..2].try_into().unwrap());
654        assert_eq!(i8_conv_back, -16);
655        i8_conv_back = i8::from_be_bytes(raw[2..3].try_into().unwrap());
656        assert_eq!(i8_conv_back, -126);
657    }
658
659    #[test]
660    fn conversion_test_string() {
661        let param: Params = "Test String".into();
662        if let Params::String(str) = param {
663            assert_eq!(str, String::from("Test String"));
664        } else {
665            panic!("Params type is not String")
666        }
667    }
668
669    #[test]
670    fn conversion_from_slice() {
671        let test_slice: [u8; 5] = [0; 5];
672        let vec_param: Params = test_slice.as_slice().into();
673        if let Params::Vec(vec) = vec_param {
674            assert_eq!(vec, test_slice.to_vec());
675        } else {
676            panic!("Params type is not a vector")
677        }
678    }
679}