1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
use crate::{ Byte, ControlPacketType, Decode, Encode, Error, PropertiesDecoder, Property, ReasonCode, Result as SageResult, TwoByteInteger, VariableByteInteger, }; use std::io::{Read, Write}; #[derive(Debug, PartialEq, Clone)] pub struct PubRel { pub packet_identifier: u16, pub reason_code: ReasonCode, pub reason_string: Option<String>, pub user_properties: Vec<(String, String)>, } impl Default for PubRel { fn default() -> Self { PubRel { packet_identifier: 0, reason_code: ReasonCode::Success, reason_string: None, user_properties: Default::default(), } } } impl PubRel { pub fn write<W: Write>(self, writer: &mut W) -> SageResult<usize> { let mut n_bytes = TwoByteInteger(self.packet_identifier).encode(writer)?; let mut properties = Vec::new(); if let Some(v) = self.reason_string { n_bytes += Property::ReasonString(v).encode(&mut properties)?; } for (k, v) in self.user_properties { n_bytes += Property::UserProperty(k, v).encode(&mut properties)?; } if n_bytes == 2 && self.reason_code != ReasonCode::Success { Ok(2) } else { n_bytes += Byte(self.reason_code as u8).encode(writer)?; n_bytes += VariableByteInteger(properties.len() as u32).encode(writer)?; writer.write_all(&properties)?; Ok(n_bytes) } } pub fn read<R: Read>(reader: &mut R, shortened: bool) -> SageResult<Self> { let packet_identifier = TwoByteInteger::decode(reader)?.into(); let mut pubrel = PubRel { packet_identifier, ..Default::default() }; if shortened { pubrel.reason_code = ReasonCode::Success; } else { pubrel.reason_code = ReasonCode::try_parse(Byte::decode(reader)?.into(), ControlPacketType::PUBREL)?; let mut properties = PropertiesDecoder::take(reader)?; while properties.has_properties() { match properties.read()? { Property::ReasonString(v) => pubrel.reason_string = Some(v), Property::UserProperty(k, v) => pubrel.user_properties.push((k, v)), _ => return Err(Error::ProtocolError), } } } Ok(pubrel) } }