rmqtt_codec/v5/packet/
auth.rs1use bytes::{Buf, BufMut, Bytes, BytesMut};
2use bytestring::ByteString;
3
4use crate::error::{DecodeError, EncodeError};
5use crate::utils::{self, Decode, Property};
6use crate::v5::{encode::*, property_type as pt, UserProperties, UserProperty};
7
8#[derive(Debug, PartialEq, Eq, Clone)]
10pub struct Auth {
11 pub reason_code: AuthReasonCode,
12 pub auth_method: Option<ByteString>,
13 pub auth_data: Option<Bytes>,
14 pub reason_string: Option<ByteString>,
15 pub user_properties: UserProperties,
16}
17
18prim_enum! {
19 pub enum AuthReasonCode {
21 Success = 0,
22 ContinueAuth = 24,
23 ReAuth = 25
24 }
25}
26
27impl From<AuthReasonCode> for u8 {
28 fn from(v: AuthReasonCode) -> Self {
29 match v {
30 AuthReasonCode::Success => 0,
31 AuthReasonCode::ContinueAuth => 24,
32 AuthReasonCode::ReAuth => 25,
33 }
34 }
35}
36
37impl Auth {
38 pub(crate) fn decode(src: &mut Bytes) -> Result<Self, DecodeError> {
39 let auth = if src.has_remaining() {
40 let reason_code = src.get_u8().try_into()?;
41
42 if src.has_remaining() {
43 let mut auth_method = None;
44 let mut auth_data = None;
45 let mut reason_string = None;
46 let mut user_properties = Vec::new();
47
48 if reason_code != AuthReasonCode::Success || src.has_remaining() {
49 let prop_src = &mut utils::take_properties(src)?;
50 while prop_src.has_remaining() {
51 match prop_src.get_u8() {
52 pt::AUTH_METHOD => auth_method.read_value(prop_src)?,
53 pt::AUTH_DATA => auth_data.read_value(prop_src)?,
54 pt::REASON_STRING => reason_string.read_value(prop_src)?,
55 pt::USER => user_properties.push(UserProperty::decode(prop_src)?),
56 _ => return Err(DecodeError::MalformedPacket),
57 }
58 }
59 ensure!(!src.has_remaining(), DecodeError::InvalidLength);
60 }
61
62 Self { reason_code, auth_method, auth_data, reason_string, user_properties }
63 } else {
64 Self { reason_code, ..Default::default() }
65 }
66 } else {
67 Self::default()
68 };
69 Ok(auth)
70 }
71}
72
73impl Default for Auth {
74 fn default() -> Self {
75 Self {
76 reason_code: AuthReasonCode::Success,
77 auth_method: None,
78 auth_data: None,
79 reason_string: None,
80 user_properties: Vec::new(),
81 }
82 }
83}
84
85impl EncodeLtd for Auth {
86 fn encoded_size(&self, limit: u32) -> usize {
87 const HEADER_LEN: usize = 1; let mut prop_len = encoded_property_size(&self.auth_method) + encoded_property_size(&self.auth_data);
90 let diag_len = encoded_size_opt_props(
91 &self.user_properties,
92 &self.reason_string,
93 reduce_limit(limit, prop_len + HEADER_LEN + 4),
94 ); prop_len += diag_len;
96 HEADER_LEN + var_int_len(prop_len) as usize + prop_len
97 }
98
99 fn encode(&self, buf: &mut BytesMut, size: u32) -> Result<(), EncodeError> {
100 let start_len = buf.len();
101 buf.put_u8(self.reason_code.into());
102
103 let prop_len = var_int_len_from_size(size - 1);
104 utils::write_variable_length(prop_len, buf);
105 encode_property(&self.auth_method, pt::AUTH_METHOD, buf)?;
106 encode_property(&self.auth_data, pt::AUTH_DATA, buf)?;
107 encode_opt_props(
108 &self.user_properties,
109 &self.reason_string,
110 buf,
111 size - (buf.len() - start_len) as u32,
112 )
113 }
114}