moq_transport/coding/
tuple.rs1use super::{Decode, DecodeError, Encode, EncodeError};
2use core::hash::{Hash, Hasher};
3
4#[derive(Clone, Debug, Default, Eq, PartialEq)]
6pub struct TupleField {
7 pub value: Vec<u8>,
8}
9
10impl TupleField {
11 pub const MAX_VALUE_SIZE: usize = 4096;
15}
16
17impl Hash for TupleField {
18 fn hash<H: Hasher>(&self, state: &mut H) {
19 self.value.hash(state);
20 }
21}
22
23impl Decode for TupleField {
24 fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
25 let size = usize::decode(r)?;
26 if size > Self::MAX_VALUE_SIZE {
27 return Err(DecodeError::FieldBoundsExceeded("TupleField".to_string()));
28 }
29 Self::decode_remaining(r, size)?;
30 let mut buf = vec![0; size];
31 r.copy_to_slice(&mut buf);
32 Ok(Self { value: buf })
33 }
34}
35
36impl Encode for TupleField {
37 fn encode<W: bytes::BufMut>(&self, w: &mut W) -> Result<(), EncodeError> {
38 if self.value.len() > Self::MAX_VALUE_SIZE {
39 return Err(EncodeError::FieldBoundsExceeded("TupleField".to_string()));
40 }
41 self.value.len().encode(w)?;
42 Self::encode_remaining(w, self.value.len())?;
43 w.put_slice(&self.value);
44 Ok(())
45 }
46}
47
48impl TupleField {
49 pub fn new() -> Self {
50 Self::default()
51 }
52
53 pub fn from_utf8(path: &str) -> Self {
54 let mut field = TupleField::new();
55 field.value = path.as_bytes().to_vec();
56 field
57 }
58
59 pub fn set<P: Encode>(&mut self, p: P) -> Result<(), EncodeError> {
62 let mut value = Vec::new();
63 p.encode(&mut value)?;
64 self.value = value;
65 Ok(())
66 }
67
68 pub fn get<P: Decode>(&self) -> Result<P, DecodeError> {
71 P::decode(&mut bytes::Bytes::from(self.value.clone()))
72 }
73}
74
75#[derive(Clone, Debug, Default, Eq, PartialEq)]
77pub struct Tuple {
78 pub fields: Vec<TupleField>,
79}
80
81impl Hash for Tuple {
82 fn hash<H: Hasher>(&self, state: &mut H) {
83 self.fields.hash(state);
84 }
85}
86
87impl Decode for Tuple {
88 fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
89 let count = usize::decode(r)?;
90 let mut fields = Vec::new();
91 for _ in 0..count {
92 fields.push(TupleField::decode(r)?);
93 }
94 Ok(Self { fields })
95 }
96}
97
98impl Encode for Tuple {
99 fn encode<W: bytes::BufMut>(&self, w: &mut W) -> Result<(), EncodeError> {
100 self.fields.len().encode(w)?;
101 for field in &self.fields {
102 field.encode(w)?;
103 }
104 Ok(())
105 }
106}
107
108impl Tuple {
109 pub fn new() -> Self {
110 Self::default()
111 }
112
113 pub fn add(&mut self, field: TupleField) {
114 self.fields.push(field);
115 }
116
117 pub fn set(&mut self, index: usize, f: TupleField) -> Result<(), EncodeError> {
118 self.fields[index].set(f)
119 }
120
121 pub fn get(&self, index: usize) -> Result<TupleField, DecodeError> {
122 self.fields[index].get()
123 }
124
125 pub fn clear(&mut self) {
126 self.fields.clear();
127 }
128
129 pub fn from_utf8_path(path: &str) -> Self {
130 let mut tuple = Tuple::new();
131 for part in path.split('/') {
132 tuple.add(TupleField::from_utf8(part));
133 }
134 tuple
135 }
136
137 pub fn to_utf8_path(&self) -> String {
138 let mut path = String::new();
139 for field in &self.fields {
140 path.push('/');
141 path.push_str(&String::from_utf8_lossy(&field.value));
142 }
143 path
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150 use bytes::Bytes;
151 use bytes::BytesMut;
152
153 #[test]
154 fn encode_decode() {
155 let mut buf = BytesMut::new();
156
157 let t = Tuple::from_utf8_path("test/path/to/resource");
158 t.encode(&mut buf).unwrap();
159 #[rustfmt::skip]
160 assert_eq!(
161 buf.to_vec(),
162 vec![
163 0x04, 0x04, 0x74, 0x65, 0x73, 0x74,
166 0x04, 0x70, 0x61, 0x74, 0x68,
168 0x02, 0x74, 0x6f,
170 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65
172 ]
173 );
174 let decoded = Tuple::decode(&mut buf).unwrap();
175 assert_eq!(decoded, t);
176
177 let mut t = Tuple::new();
179 t.add(TupleField::from_utf8("test"));
180 t.encode(&mut buf).unwrap();
181 assert_eq!(
182 buf.to_vec(),
183 vec![
184 0x01, 0x04, 0x74, 0x65, 0x73, 0x74
186 ]
187 ); let decoded = Tuple::decode(&mut buf).unwrap();
189 assert_eq!(decoded, t);
190 }
191
192 #[test]
193 fn encode_tuplefield_too_large() {
194 let mut buf = BytesMut::new();
195
196 let t = TupleField {
197 value: vec![0; TupleField::MAX_VALUE_SIZE + 1], };
199
200 let encoded = t.encode(&mut buf);
201 assert!(matches!(
202 encoded.unwrap_err(),
203 EncodeError::FieldBoundsExceeded(_)
204 ));
205 }
206
207 #[test]
208 fn decode_tuplefield_too_large() {
209 let mut data: Vec<u8> = vec![0x00; TupleField::MAX_VALUE_SIZE + 1]; data[0] = 0x50;
212 data[1] = 0x01;
213 let mut buf: Bytes = data.into();
214 let decoded = TupleField::decode(&mut buf);
215 assert!(matches!(
216 decoded.unwrap_err(),
217 DecodeError::FieldBoundsExceeded(_)
218 ));
219 }
220}