mqute_codec/protocol/common/
payload.rs1use crate::codec::util::{decode_string, encode_string};
9use crate::Error;
10use bytes::{Buf, BufMut, Bytes, BytesMut};
11use std::borrow::Borrow;
12use std::ops::{Index, IndexMut};
13
14#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct Codes<T>(Vec<T>);
29
30#[allow(clippy::len_without_is_empty)]
31impl<T> Codes<T>
32where
33 T: TryFrom<u8, Error = Error> + Into<u8> + Copy,
34{
35 pub fn new<I: IntoIterator<Item = T>>(codes: I) -> Self {
41 let values: Vec<T> = codes.into_iter().collect();
42
43 if values.is_empty() {
44 panic!("At least one code is required");
45 }
46
47 Codes(values)
48 }
49
50 pub(crate) fn decode(payload: &mut Bytes) -> Result<Self, Error> {
52 let mut codes: Vec<T> = Vec::with_capacity(payload.len());
53 while payload.has_remaining() {
54 codes.push(payload.get_u8().try_into()?);
55 }
56
57 if codes.is_empty() {
58 return Err(Error::NoCodes);
59 }
60
61 Ok(codes.into())
62 }
63
64 pub(crate) fn encode(&self, buf: &mut BytesMut) {
66 self.0.iter().for_each(|&value| {
67 buf.put_u8(value.into());
68 });
69 }
70
71 pub fn len(&self) -> usize {
73 self.0.len()
74 }
75}
76
77impl<T> AsRef<Vec<T>> for Codes<T> {
78 #[inline]
79 fn as_ref(&self) -> &Vec<T> {
80 self.0.as_ref()
81 }
82}
83
84impl<T> Borrow<Vec<T>> for Codes<T> {
85 fn borrow(&self) -> &Vec<T> {
86 self.0.as_ref()
87 }
88}
89
90impl<T> IntoIterator for Codes<T> {
91 type Item = T;
92 type IntoIter = std::vec::IntoIter<T>;
93
94 fn into_iter(self) -> Self::IntoIter {
95 self.0.into_iter()
96 }
97}
98
99impl<T> FromIterator<T> for Codes<T> {
100 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
101 Codes(Vec::from_iter(iter))
102 }
103}
104
105impl<T> From<Codes<T>> for Vec<T> {
106 #[inline]
107 fn from(value: Codes<T>) -> Self {
108 value.0
109 }
110}
111
112impl<T> From<Vec<T>> for Codes<T> {
113 #[inline]
114 fn from(value: Vec<T>) -> Self {
115 Codes(value)
116 }
117}
118
119#[derive(Debug, Clone, PartialEq, Eq)]
132pub struct TopicFilters(Vec<String>);
133
134#[allow(clippy::len_without_is_empty)]
135impl TopicFilters {
136 pub fn new<T: IntoIterator<Item: Into<String>>>(filters: T) -> Self {
142 let values: Vec<String> = filters.into_iter().map(|x| x.into()).collect();
143
144 if values.is_empty() {
145 panic!("At least one topic filter is required");
146 }
147
148 TopicFilters(values)
149 }
150
151 pub fn len(&self) -> usize {
153 self.0.len()
154 }
155
156 pub(crate) fn decode(payload: &mut Bytes) -> Result<Self, Error> {
158 let mut filters = Vec::with_capacity(1);
159
160 while payload.has_remaining() {
161 let filter = decode_string(payload)?;
162
163 filters.push(filter);
164 }
165
166 if filters.is_empty() {
167 return Err(Error::NoTopic);
168 }
169
170 Ok(TopicFilters(filters))
171 }
172
173 pub(crate) fn encode(&self, buf: &mut BytesMut) {
175 self.0.iter().for_each(|filter| {
176 encode_string(buf, filter);
177 });
178 }
179
180 pub(crate) fn encoded_len(&self) -> usize {
182 self.0.iter().fold(0, |acc, filter| acc + 2 + filter.len())
183 }
184}
185
186impl AsRef<Vec<String>> for TopicFilters {
187 #[inline]
188 fn as_ref(&self) -> &Vec<String> {
189 self.0.as_ref()
190 }
191}
192
193impl Borrow<Vec<String>> for TopicFilters {
194 fn borrow(&self) -> &Vec<String> {
195 self.0.as_ref()
196 }
197}
198
199impl IntoIterator for TopicFilters {
200 type Item = String;
201 type IntoIter = std::vec::IntoIter<String>;
202
203 fn into_iter(self) -> Self::IntoIter {
204 self.0.into_iter()
205 }
206}
207
208impl FromIterator<String> for TopicFilters {
209 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
210 TopicFilters(Vec::from_iter(iter))
211 }
212}
213
214impl From<TopicFilters> for Vec<String> {
215 #[inline]
216 fn from(value: TopicFilters) -> Self {
217 value.0
218 }
219}
220
221impl From<Vec<String>> for TopicFilters {
222 #[inline]
223 fn from(value: Vec<String>) -> Self {
224 TopicFilters(value)
225 }
226}
227
228impl<T> Index<usize> for Codes<T> {
229 type Output = T;
230 fn index(&self, index: usize) -> &Self::Output {
231 self.0.index(index)
232 }
233}
234
235impl<T> IndexMut<usize> for Codes<T> {
236 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
237 self.0.index_mut(index)
238 }
239}