1use core::fmt::Debug;
31use core::hash::Hash;
32use core::marker::PhantomData;
33use delegate::delegate;
34use spacepackets::ecss::EcssEnumeration;
35use spacepackets::util::{ToBeBytes, UnsignedEnum};
36use spacepackets::ByteConversionError;
37
38pub type LargestEventRaw = u32;
40pub type LargestGroupIdRaw = u16;
42
43#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
44pub enum Severity {
45 INFO = 0,
46 LOW = 1,
47 MEDIUM = 2,
48 HIGH = 3,
49}
50
51pub trait HasSeverity: Debug + PartialEq + Eq + Copy + Clone {
52 const SEVERITY: Severity;
53}
54
55#[derive(Debug, PartialEq, Eq, Copy, Clone)]
57pub struct SeverityInfo {}
58impl HasSeverity for SeverityInfo {
59 const SEVERITY: Severity = Severity::INFO;
60}
61
62#[derive(Debug, PartialEq, Eq, Copy, Clone)]
64pub struct SeverityLow {}
65impl HasSeverity for SeverityLow {
66 const SEVERITY: Severity = Severity::LOW;
67}
68
69#[derive(Debug, PartialEq, Eq, Copy, Clone)]
71pub struct SeverityMedium {}
72impl HasSeverity for SeverityMedium {
73 const SEVERITY: Severity = Severity::MEDIUM;
74}
75
76#[derive(Debug, PartialEq, Eq, Copy, Clone)]
78pub struct SeverityHigh {}
79impl HasSeverity for SeverityHigh {
80 const SEVERITY: Severity = Severity::HIGH;
81}
82
83pub trait GenericEvent: EcssEnumeration {
84 type Raw;
85 type GroupId;
86 type UniqueId;
87
88 fn raw(&self) -> Self::Raw;
89 fn severity(&self) -> Severity;
90 fn group_id(&self) -> Self::GroupId;
91 fn unique_id(&self) -> Self::UniqueId;
92
93 fn raw_as_largest_type(&self) -> LargestEventRaw;
94 fn group_id_as_largest_type(&self) -> LargestGroupIdRaw;
95}
96
97impl TryFrom<u8> for Severity {
98 type Error = ();
99
100 fn try_from(value: u8) -> Result<Self, Self::Error> {
101 match value {
102 x if x == Severity::INFO as u8 => Ok(Severity::INFO),
103 x if x == Severity::LOW as u8 => Ok(Severity::LOW),
104 x if x == Severity::MEDIUM as u8 => Ok(Severity::MEDIUM),
105 x if x == Severity::HIGH as u8 => Ok(Severity::HIGH),
106 _ => Err(()),
107 }
108 }
109}
110
111#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
112struct EventBase<RAW, GID, UID> {
113 severity: Severity,
114 group_id: GID,
115 unique_id: UID,
116 phantom: PhantomData<RAW>,
117}
118
119impl<RAW: ToBeBytes, GID, UID> EventBase<RAW, GID, UID> {
120 fn write_to_bytes(
121 &self,
122 raw: RAW,
123 buf: &mut [u8],
124 width: usize,
125 ) -> Result<usize, ByteConversionError> {
126 if buf.len() < width {
127 return Err(ByteConversionError::ToSliceTooSmall {
128 found: buf.len(),
129 expected: width,
130 });
131 }
132 buf.copy_from_slice(raw.to_be_bytes().as_ref());
133 Ok(raw.written_len())
134 }
135}
136
137impl EventBase<u32, u16, u16> {
138 #[inline]
139 fn raw(&self) -> u32 {
140 ((self.severity as u32) << 30) | ((self.group_id as u32) << 16) | self.unique_id as u32
141 }
142}
143
144impl EventBase<u16, u8, u8> {
145 #[inline]
146 fn raw(&self) -> u16 {
147 ((self.severity as u16) << 14) | ((self.group_id as u16) << 8) | self.unique_id as u16
148 }
149}
150
151impl<RAW, GID, UID> EventBase<RAW, GID, UID> {
152 #[inline]
153 pub fn severity(&self) -> Severity {
154 self.severity
155 }
156}
157
158impl<RAW, GID> EventBase<RAW, GID, u16> {
159 #[inline]
160 pub fn unique_id(&self) -> u16 {
161 self.unique_id
162 }
163}
164
165impl<RAW, GID> EventBase<RAW, GID, u8> {
166 #[inline]
167 pub fn unique_id(&self) -> u8 {
168 self.unique_id
169 }
170}
171
172impl<RAW, UID> EventBase<RAW, u16, UID> {
173 #[inline]
174 pub fn group_id(&self) -> u16 {
175 self.group_id
176 }
177}
178
179impl<RAW, UID> EventBase<RAW, u8, UID> {
180 #[inline]
181 pub fn group_id(&self) -> u8 {
182 self.group_id
183 }
184}
185
186macro_rules! event_provider_impl {
187 () => {
188 #[inline]
189 fn raw(&self) -> Self::Raw {
190 self.base.raw()
191 }
192
193 #[inline]
196 fn severity(&self) -> Severity {
197 self.base.severity()
198 }
199
200 #[inline]
201 fn group_id(&self) -> Self::GroupId {
202 self.base.group_id()
203 }
204
205 #[inline]
206 fn unique_id(&self) -> Self::UniqueId {
207 self.base.unique_id()
208 }
209 };
210}
211
212macro_rules! impl_event_provider {
213 ($BaseIdent: ident, $TypedIdent: ident, $raw: ty, $gid: ty, $uid: ty) => {
214 impl GenericEvent for $BaseIdent {
215 type Raw = $raw;
216 type GroupId = $gid;
217 type UniqueId = $uid;
218
219 event_provider_impl!();
220
221 fn raw_as_largest_type(&self) -> LargestEventRaw {
222 self.raw().into()
223 }
224
225 fn group_id_as_largest_type(&self) -> LargestGroupIdRaw {
226 self.group_id().into()
227 }
228 }
229
230 impl<SEVERITY: HasSeverity> GenericEvent for $TypedIdent<SEVERITY> {
231 type Raw = $raw;
232 type GroupId = $gid;
233 type UniqueId = $uid;
234
235 delegate!(to self.event {
236 fn raw(&self) -> Self::Raw;
237 fn severity(&self) -> Severity;
238 fn group_id(&self) -> Self::GroupId;
239 fn unique_id(&self) -> Self::UniqueId;
240 fn raw_as_largest_type(&self) -> LargestEventRaw;
241 fn group_id_as_largest_type(&self) -> LargestGroupIdRaw;
242 });
243 }
244 }
245}
246
247macro_rules! try_from_impls {
248 ($SevIdent: ident, $severity: path, $raw: ty, $TypedSevIdent: ident) => {
249 impl TryFrom<$raw> for $TypedSevIdent<$SevIdent> {
250 type Error = Severity;
251
252 fn try_from(raw: $raw) -> Result<Self, Self::Error> {
253 Self::try_from_generic($severity, raw)
254 }
255 }
256 };
257}
258
259macro_rules! const_from_fn {
260 ($from_fn_name: ident, $TypedIdent: ident, $SevIdent: ident) => {
261 pub const fn $from_fn_name(event: $TypedIdent<$SevIdent>) -> Self {
262 Self {
263 base: event.event.base,
264 }
265 }
266 };
267}
268
269#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
270pub struct EventU32 {
271 base: EventBase<u32, u16, u16>,
272}
273
274#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
275pub struct EventU32TypedSev<SEVERITY> {
276 event: EventU32,
277 phantom: PhantomData<SEVERITY>,
278}
279
280impl<SEVERITY: HasSeverity> From<EventU32TypedSev<SEVERITY>> for EventU32 {
281 fn from(e: EventU32TypedSev<SEVERITY>) -> Self {
282 Self { base: e.event.base }
283 }
284}
285
286impl<Severity: HasSeverity> AsRef<EventU32> for EventU32TypedSev<Severity> {
287 fn as_ref(&self) -> &EventU32 {
288 &self.event
289 }
290}
291
292impl<Severity: HasSeverity> AsMut<EventU32> for EventU32TypedSev<Severity> {
293 fn as_mut(&mut self) -> &mut EventU32 {
294 &mut self.event
295 }
296}
297
298impl_event_provider!(EventU32, EventU32TypedSev, u32, u16, u16);
299
300impl EventU32 {
301 pub fn new(
313 severity: Severity,
314 group_id: <Self as GenericEvent>::GroupId,
315 unique_id: <Self as GenericEvent>::UniqueId,
316 ) -> Option<Self> {
317 if group_id > (2u16.pow(14) - 1) {
318 return None;
319 }
320 Some(Self {
321 base: EventBase {
322 severity,
323 group_id,
324 unique_id,
325 phantom: PhantomData,
326 },
327 })
328 }
329 pub const fn const_new(
330 severity: Severity,
331 group_id: <Self as GenericEvent>::GroupId,
332 unique_id: <Self as GenericEvent>::UniqueId,
333 ) -> Self {
334 if group_id > (2u16.pow(14) - 1) {
335 panic!("Group ID too large");
336 }
337 Self {
338 base: EventBase {
339 severity,
340 group_id,
341 unique_id,
342 phantom: PhantomData,
343 },
344 }
345 }
346
347 const_from_fn!(const_from_info, EventU32TypedSev, SeverityInfo);
348 const_from_fn!(const_from_low, EventU32TypedSev, SeverityLow);
349 const_from_fn!(const_from_medium, EventU32TypedSev, SeverityMedium);
350 const_from_fn!(const_from_high, EventU32TypedSev, SeverityHigh);
351}
352
353impl<SEVERITY: HasSeverity> EventU32TypedSev<SEVERITY> {
354 pub fn new(
357 group_id: <Self as GenericEvent>::GroupId,
358 unique_id: <Self as GenericEvent>::UniqueId,
359 ) -> Option<Self> {
360 let event = EventU32::new(SEVERITY::SEVERITY, group_id, unique_id)?;
361 Some(Self {
362 event,
363 phantom: PhantomData,
364 })
365 }
366
367 pub const fn const_new(
369 group_id: <Self as GenericEvent>::GroupId,
370 unique_id: <Self as GenericEvent>::UniqueId,
371 ) -> Self {
372 let event = EventU32::const_new(SEVERITY::SEVERITY, group_id, unique_id);
373 Self {
374 event,
375 phantom: PhantomData,
376 }
377 }
378
379 fn try_from_generic(expected: Severity, raw: u32) -> Result<Self, Severity> {
380 let severity = Severity::try_from(((raw >> 30) & 0b11) as u8).unwrap();
381 if severity != expected {
382 return Err(severity);
383 }
384 Ok(Self::const_new(
385 ((raw >> 16) & 0x3FFF) as u16,
386 (raw & 0xFFFF) as u16,
387 ))
388 }
389}
390
391impl From<u32> for EventU32 {
392 fn from(raw: u32) -> Self {
393 let severity = Severity::try_from(((raw >> 30) & 0b11) as u8).unwrap();
395 let group_id = ((raw >> 16) & 0x3FFF) as u16;
396 let unique_id = (raw & 0xFFFF) as u16;
397 Self::const_new(severity, group_id, unique_id)
399 }
400}
401
402try_from_impls!(SeverityInfo, Severity::INFO, u32, EventU32TypedSev);
403try_from_impls!(SeverityLow, Severity::LOW, u32, EventU32TypedSev);
404try_from_impls!(SeverityMedium, Severity::MEDIUM, u32, EventU32TypedSev);
405try_from_impls!(SeverityHigh, Severity::HIGH, u32, EventU32TypedSev);
406
407impl UnsignedEnum for EventU32 {
408 fn size(&self) -> usize {
409 core::mem::size_of::<u32>()
410 }
411
412 fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
413 self.base.write_to_bytes(self.raw(), buf, self.size())
414 }
415}
416
417impl EcssEnumeration for EventU32 {
418 fn pfc(&self) -> u8 {
419 u32::BITS as u8
420 }
421}
422
423impl<SEVERITY: HasSeverity> UnsignedEnum for EventU32TypedSev<SEVERITY> {
425 delegate!(to self.event {
426 fn size(&self) -> usize;
427 fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError>;
428 });
429}
430
431impl<SEVERITY: HasSeverity> EcssEnumeration for EventU32TypedSev<SEVERITY> {
433 delegate!(to self.event {
434 fn pfc(&self) -> u8;
435 });
436}
437
438#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
439pub struct EventU16 {
440 base: EventBase<u16, u8, u8>,
441}
442
443#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
444pub struct EventU16TypedSev<SEVERITY> {
445 event: EventU16,
446 phantom: PhantomData<SEVERITY>,
447}
448
449impl<Severity: HasSeverity> AsRef<EventU16> for EventU16TypedSev<Severity> {
450 fn as_ref(&self) -> &EventU16 {
451 &self.event
452 }
453}
454
455impl<Severity: HasSeverity> AsMut<EventU16> for EventU16TypedSev<Severity> {
456 fn as_mut(&mut self) -> &mut EventU16 {
457 &mut self.event
458 }
459}
460
461impl EventU16 {
462 pub fn new(
474 severity: Severity,
475 group_id: <Self as GenericEvent>::GroupId,
476 unique_id: <Self as GenericEvent>::UniqueId,
477 ) -> Option<Self> {
478 if group_id > (2u8.pow(6) - 1) {
479 return None;
480 }
481 Some(Self {
482 base: EventBase {
483 severity,
484 group_id,
485 unique_id,
486 phantom: Default::default(),
487 },
488 })
489 }
490
491 pub const fn const_new(
493 severity: Severity,
494 group_id: <Self as GenericEvent>::GroupId,
495 unique_id: <Self as GenericEvent>::UniqueId,
496 ) -> Self {
497 if group_id > (2u8.pow(6) - 1) {
498 panic!("Group ID too large");
499 }
500 Self {
501 base: EventBase {
502 severity,
503 group_id,
504 unique_id,
505 phantom: PhantomData,
506 },
507 }
508 }
509 const_from_fn!(const_from_info, EventU16TypedSev, SeverityInfo);
510 const_from_fn!(const_from_low, EventU16TypedSev, SeverityLow);
511 const_from_fn!(const_from_medium, EventU16TypedSev, SeverityMedium);
512 const_from_fn!(const_from_high, EventU16TypedSev, SeverityHigh);
513}
514
515impl<SEVERITY: HasSeverity> EventU16TypedSev<SEVERITY> {
516 pub fn new(
519 group_id: <Self as GenericEvent>::GroupId,
520 unique_id: <Self as GenericEvent>::UniqueId,
521 ) -> Option<Self> {
522 let event = EventU16::new(SEVERITY::SEVERITY, group_id, unique_id)?;
523 Some(Self {
524 event,
525 phantom: PhantomData,
526 })
527 }
528
529 pub const fn const_new(
531 group_id: <Self as GenericEvent>::GroupId,
532 unique_id: <Self as GenericEvent>::UniqueId,
533 ) -> Self {
534 let event = EventU16::const_new(SEVERITY::SEVERITY, group_id, unique_id);
535 Self {
536 event,
537 phantom: PhantomData,
538 }
539 }
540
541 fn try_from_generic(expected: Severity, raw: u16) -> Result<Self, Severity> {
542 let severity = Severity::try_from(((raw >> 14) & 0b11) as u8).unwrap();
543 if severity != expected {
544 return Err(severity);
545 }
546 Ok(Self::const_new(
547 ((raw >> 8) & 0x3F) as u8,
548 (raw & 0xFF) as u8,
549 ))
550 }
551}
552
553impl_event_provider!(EventU16, EventU16TypedSev, u16, u8, u8);
554
555impl UnsignedEnum for EventU16 {
556 fn size(&self) -> usize {
557 core::mem::size_of::<u16>()
558 }
559
560 fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
561 self.base.write_to_bytes(self.raw(), buf, self.size())
562 }
563}
564impl EcssEnumeration for EventU16 {
565 #[inline]
566 fn pfc(&self) -> u8 {
567 u16::BITS as u8
568 }
569}
570
571impl<SEVERITY: HasSeverity> UnsignedEnum for EventU16TypedSev<SEVERITY> {
573 delegate!(to self.event {
574 fn size(&self) -> usize;
575 fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError>;
576 });
577}
578
579impl<SEVERITY: HasSeverity> EcssEnumeration for EventU16TypedSev<SEVERITY> {
581 delegate!(to self.event {
582 fn pfc(&self) -> u8;
583 });
584}
585
586impl From<u16> for EventU16 {
587 fn from(raw: <Self as GenericEvent>::Raw) -> Self {
588 let severity = Severity::try_from(((raw >> 14) & 0b11) as u8).unwrap();
589 let group_id = ((raw >> 8) & 0x3F) as u8;
590 let unique_id = (raw & 0xFF) as u8;
591 Self::const_new(severity, group_id, unique_id)
593 }
594}
595
596try_from_impls!(SeverityInfo, Severity::INFO, u16, EventU16TypedSev);
597try_from_impls!(SeverityLow, Severity::LOW, u16, EventU16TypedSev);
598try_from_impls!(SeverityMedium, Severity::MEDIUM, u16, EventU16TypedSev);
599try_from_impls!(SeverityHigh, Severity::HIGH, u16, EventU16TypedSev);
600
601impl<Severity: HasSeverity> PartialEq<EventU32> for EventU32TypedSev<Severity> {
602 #[inline]
603 fn eq(&self, other: &EventU32) -> bool {
604 self.raw() == other.raw()
605 }
606}
607
608impl<Severity: HasSeverity> PartialEq<EventU32TypedSev<Severity>> for EventU32 {
609 #[inline]
610 fn eq(&self, other: &EventU32TypedSev<Severity>) -> bool {
611 self.raw() == other.raw()
612 }
613}
614
615impl<Severity: HasSeverity> PartialEq<EventU16> for EventU16TypedSev<Severity> {
616 #[inline]
617 fn eq(&self, other: &EventU16) -> bool {
618 self.raw() == other.raw()
619 }
620}
621
622impl<Severity: HasSeverity> PartialEq<EventU16TypedSev<Severity>> for EventU16 {
623 #[inline]
624 fn eq(&self, other: &EventU16TypedSev<Severity>) -> bool {
625 self.raw() == other.raw()
626 }
627}
628
629#[cfg(test)]
630mod tests {
631 use super::EventU32TypedSev;
632 use super::*;
633 use spacepackets::ByteConversionError;
634 use std::mem::size_of;
635
636 fn assert_size<T>(_: T, val: usize) {
637 assert_eq!(size_of::<T>(), val);
638 }
639
640 const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::const_new(0, 0);
641 const INFO_EVENT_SMALL: EventU16TypedSev<SeverityInfo> = EventU16TypedSev::const_new(0, 0);
642 const HIGH_SEV_EVENT: EventU32TypedSev<SeverityHigh> =
643 EventU32TypedSev::const_new(0x3FFF, 0xFFFF);
644 const HIGH_SEV_EVENT_SMALL: EventU16TypedSev<SeverityHigh> =
645 EventU16TypedSev::const_new(0x3F, 0xff);
646
647 const INFO_REDUCED: EventU32 = EventU32::const_from_info(INFO_EVENT);
649
650 #[test]
651 fn test_normal_from_raw_conversion() {
652 let conv_from_raw = EventU32TypedSev::<SeverityInfo>::try_from(INFO_EVENT.raw())
653 .expect("Creating typed EventU32 failed");
654 assert_eq!(conv_from_raw, INFO_EVENT);
655 }
656
657 #[test]
658 fn test_small_from_raw_conversion() {
659 let conv_from_raw = EventU16TypedSev::<SeverityInfo>::try_from(INFO_EVENT_SMALL.raw())
660 .expect("Creating typed EventU16 failed");
661 assert_eq!(conv_from_raw, INFO_EVENT_SMALL);
662 }
663
664 #[test]
665 fn verify_normal_size() {
666 assert_size(INFO_EVENT.raw(), 4)
667 }
668
669 #[test]
670 fn verify_small_size() {
671 assert_size(INFO_EVENT_SMALL.raw(), 2)
672 }
673
674 #[test]
675 fn test_normal_event_getters() {
676 assert_eq!(INFO_EVENT.severity(), Severity::INFO);
677 assert_eq!(INFO_EVENT.unique_id(), 0);
678 assert_eq!(INFO_EVENT.group_id(), 0);
679 let raw_event = INFO_EVENT.raw();
680 assert_eq!(raw_event, 0x00000000);
681 }
682
683 #[test]
684 fn test_small_event_getters() {
685 assert_eq!(INFO_EVENT_SMALL.severity(), Severity::INFO);
686 assert_eq!(INFO_EVENT_SMALL.unique_id(), 0);
687 assert_eq!(INFO_EVENT_SMALL.group_id(), 0);
688 let raw_event = INFO_EVENT_SMALL.raw();
689 assert_eq!(raw_event, 0x00000000);
690 }
691
692 #[test]
693 fn all_ones_event_regular() {
694 assert_eq!(HIGH_SEV_EVENT.severity(), Severity::HIGH);
695 assert_eq!(HIGH_SEV_EVENT.group_id(), 0x3FFF);
696 assert_eq!(HIGH_SEV_EVENT.unique_id(), 0xFFFF);
697 let raw_event = HIGH_SEV_EVENT.raw();
698 assert_eq!(raw_event, 0xFFFFFFFF);
699 }
700
701 #[test]
702 fn all_ones_event_small() {
703 assert_eq!(HIGH_SEV_EVENT_SMALL.severity(), Severity::HIGH);
704 assert_eq!(HIGH_SEV_EVENT_SMALL.group_id(), 0x3F);
705 assert_eq!(HIGH_SEV_EVENT_SMALL.unique_id(), 0xFF);
706 let raw_event = HIGH_SEV_EVENT_SMALL.raw();
707 assert_eq!(raw_event, 0xFFFF);
708 }
709
710 #[test]
711 fn invalid_group_id_normal() {
712 assert!(EventU32TypedSev::<SeverityMedium>::new(2_u16.pow(14), 0).is_none());
713 }
714
715 #[test]
716 fn invalid_group_id_small() {
717 assert!(EventU16TypedSev::<SeverityMedium>::new(2_u8.pow(6), 0).is_none());
718 }
719
720 #[test]
721 fn regular_new() {
722 assert_eq!(
723 EventU32TypedSev::<SeverityInfo>::new(0, 0).expect("Creating regular event failed"),
724 INFO_EVENT
725 );
726 }
727
728 #[test]
729 fn small_new() {
730 assert_eq!(
731 EventU16TypedSev::<SeverityInfo>::new(0, 0).expect("Creating regular event failed"),
732 INFO_EVENT_SMALL
733 );
734 }
735
736 #[test]
737 fn as_largest_type() {
738 let event_raw = HIGH_SEV_EVENT.raw_as_largest_type();
739 assert_size(event_raw, 4);
740 assert_eq!(event_raw, 0xFFFFFFFF);
741 }
742
743 #[test]
744 fn as_largest_type_for_small_event() {
745 let event_raw = HIGH_SEV_EVENT_SMALL.raw_as_largest_type();
746 assert_size(event_raw, 4);
747 assert_eq!(event_raw, 0xFFFF);
748 }
749
750 #[test]
751 fn as_largest_group_id() {
752 let group_id = HIGH_SEV_EVENT.group_id_as_largest_type();
753 assert_size(group_id, 2);
754 assert_eq!(group_id, 0x3FFF);
755 }
756
757 #[test]
758 fn as_largest_group_id_small_event() {
759 let group_id = HIGH_SEV_EVENT_SMALL.group_id_as_largest_type();
760 assert_size(group_id, 2);
761 assert_eq!(group_id, 0x3F);
762 }
763
764 #[test]
765 fn write_to_buf() {
766 let mut buf: [u8; 4] = [0; 4];
767 assert!(HIGH_SEV_EVENT.write_to_be_bytes(&mut buf).is_ok());
768 let val_from_raw = u32::from_be_bytes(buf);
769 assert_eq!(val_from_raw, 0xFFFFFFFF);
770 }
771
772 #[test]
773 fn write_to_buf_small() {
774 let mut buf: [u8; 2] = [0; 2];
775 assert!(HIGH_SEV_EVENT_SMALL.write_to_be_bytes(&mut buf).is_ok());
776 let val_from_raw = u16::from_be_bytes(buf);
777 assert_eq!(val_from_raw, 0xFFFF);
778 }
779
780 #[test]
781 fn write_to_buf_insufficient_buf() {
782 let mut buf: [u8; 3] = [0; 3];
783 let err = HIGH_SEV_EVENT.write_to_be_bytes(&mut buf);
784 assert!(err.is_err());
785 let err = err.unwrap_err();
786 if let ByteConversionError::ToSliceTooSmall { found, expected } = err {
787 assert_eq!(expected, 4);
788 assert_eq!(found, 3);
789 }
790 }
791
792 #[test]
793 fn write_to_buf_small_insufficient_buf() {
794 let mut buf: [u8; 1] = [0; 1];
795 let err = HIGH_SEV_EVENT_SMALL.write_to_be_bytes(&mut buf);
796 assert!(err.is_err());
797 let err = err.unwrap_err();
798 if let ByteConversionError::ToSliceTooSmall { found, expected } = err {
799 assert_eq!(expected, 2);
800 assert_eq!(found, 1);
801 }
802 }
803
804 #[test]
805 fn severity_from_invalid_raw_val() {
806 let invalid = 0xFF;
807 assert!(Severity::try_from(invalid).is_err());
808 let invalid = Severity::HIGH as u8 + 1;
809 assert!(Severity::try_from(invalid).is_err());
810 }
811
812 #[test]
813 fn reduction() {
814 let event = EventU32TypedSev::<SeverityInfo>::const_new(1, 1);
815 let raw = event.raw();
816 let reduced: EventU32 = event.into();
817 assert_eq!(reduced.group_id(), 1);
818 assert_eq!(reduced.unique_id(), 1);
819 assert_eq!(raw, reduced.raw());
820 }
821
822 #[test]
823 fn const_reducation() {
824 assert_eq!(INFO_REDUCED.raw(), INFO_EVENT.raw());
825 }
826}