1use std::fmt;
2use std::io::{Error, Read, Write};
3
4use byteorder::{ReadBytesExt, WriteBytesExt};
5
6use crate::*;
7
8#[derive(Clone, Debug)]
10pub struct Notification {
11 pub major_err_code: u8,
13 pub minor_err_code: u8,
15 pub data: Vec<u8>,
17}
18
19impl Notification {
20 pub fn parse(header: &Header, stream: &mut impl Read) -> Result<Notification, Error> {
23 let major_err_code = stream.read_u8()?;
24 let minor_err_code = stream.read_u8()?;
25 let data = if header.length > 21 {
26 let remaining_length = header.length as usize - 21;
27 let mut data = vec![0; remaining_length as usize];
28 stream.read_exact(&mut data)?;
29 data
30 } else {
31 vec![]
32 };
33
34 Ok(Notification {
35 major_err_code,
36 minor_err_code,
37 data,
38 })
39 }
40
41 pub fn encode(&self, buf: &mut impl Write) -> Result<(), Error> {
43 buf.write_u8(self.major_err_code)?;
44 buf.write_u8(self.minor_err_code)?;
45 buf.write_all(&self.data)
46 }
47
48 pub fn major(&self) -> String {
50 match self.major_err_code {
51 1 => "Message Header Error".to_string(),
52 2 => "OPEN Message Error".to_string(),
53 3 => "UPDATE Message Error".to_string(),
54 4 => "Hold Timer Expired".to_string(),
55 5 => "Finite State Machine".to_string(),
56 6 => "Cease".to_string(),
57 _ => format!("Major Code {}", self.major_err_code),
58 }
59 }
60 pub fn minor(&self) -> String {
62 format!("{}", self.minor_err_code)
63 }
64
65 pub fn message(&self) -> Option<String> {
67 String::from_utf8(self.data.clone()).ok()
68 }
69}
70
71impl fmt::Display for Notification {
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73 write!(
74 f,
75 "{} / {} {}",
76 self.major(),
77 self.minor(),
78 self.message().unwrap_or_else(|| "".to_string())
79 )
80 }
81}
82
83#[test]
84fn test_notification_display() {
85 let notification = Notification {
86 major_err_code: 6,
87 minor_err_code: 3,
88 data: vec![],
89 };
90 assert_eq!(¬ification.to_string(), "Cease / 3 ");
91 let notification = Notification {
92 major_err_code: 2,
93 minor_err_code: 1,
94 data: b"Unsupported Capability".to_vec(),
95 };
96 assert_eq!(
97 ¬ification.to_string(),
98 "OPEN Message Error / 1 Unsupported Capability"
99 );
100}