dove/
encoding.rs

1/*
2 * Copyright 2020, Ulf Lilleengen
3 * License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
4 */
5
6//! The encoding module contains AMQP 1.0 type encoders and rust native types encoders.
7
8use byteorder::NetworkEndian;
9use byteorder::WriteBytesExt;
10use std::collections::BTreeMap;
11use std::io::Write;
12use std::vec::Vec;
13
14use crate::error::*;
15use crate::frame_codec::*;
16use crate::symbol::*;
17use crate::types::*;
18
19/**
20 * This is the main encoder implementation for AMQP types.
21 */
22impl Encoder for ValueRef<'_> {
23    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
24        let value = self;
25        match *value {
26            ValueRef::Described(ref descriptor, ref value) => {
27                writer.write_u8(0)?;
28                descriptor.encode(writer)?;
29                value.encode(writer)?;
30                Ok(TypeCode::Described)
31            }
32            ValueRef::Null => {
33                writer.write_u8(TypeCode::Null as u8)?;
34                Ok(TypeCode::Null)
35            }
36            ValueRef::Bool(value) => {
37                let code = if *value {
38                    TypeCode::BooleanTrue
39                } else {
40                    TypeCode::BooleanFalse
41                };
42                writer.write_u8(code as u8)?;
43
44                Ok(code)
45            }
46            ValueRef::String(val) => {
47                if val.len() > U8_MAX {
48                    writer.write_u8(TypeCode::Str32 as u8)?;
49                    writer.write_u32::<NetworkEndian>(val.len() as u32)?;
50                    writer.write_all(val.as_bytes())?;
51                    Ok(TypeCode::Str32)
52                } else {
53                    writer.write_u8(TypeCode::Str8 as u8)?;
54                    writer.write_u8(val.len() as u8)?;
55                    writer.write_all(val.as_bytes())?;
56                    Ok(TypeCode::Str8)
57                }
58            }
59            ValueRef::SymbolRef(val) => {
60                if val.len() > U8_MAX {
61                    writer.write_u8(TypeCode::Sym32 as u8)?;
62                    writer.write_u32::<NetworkEndian>(val.len() as u32)?;
63                    writer.write_all(val.as_bytes())?;
64                    Ok(TypeCode::Sym32)
65                } else {
66                    writer.write_u8(TypeCode::Sym8 as u8)?;
67                    writer.write_u8(val.len() as u8)?;
68                    writer.write_all(val.as_bytes())?;
69                    Ok(TypeCode::Sym8)
70                }
71            }
72            ValueRef::Symbol(val) => {
73                if val.len() > U8_MAX {
74                    writer.write_u8(TypeCode::Sym32 as u8)?;
75                    writer.write_u32::<NetworkEndian>(val.len() as u32)?;
76                    writer.write_all(val)?;
77                    Ok(TypeCode::Sym32)
78                } else {
79                    writer.write_u8(TypeCode::Sym8 as u8)?;
80                    writer.write_u8(val.len() as u8)?;
81                    writer.write_all(val)?;
82                    Ok(TypeCode::Sym8)
83                }
84            }
85            ValueRef::Binary(val) => {
86                if val.len() > U8_MAX {
87                    writer.write_u8(TypeCode::Bin32 as u8)?;
88                    writer.write_u32::<NetworkEndian>(val.len() as u32)?;
89                    writer.write_all(val)?;
90                    Ok(TypeCode::Bin32)
91                } else {
92                    writer.write_u8(TypeCode::Bin8 as u8)?;
93                    writer.write_u8(val.len() as u8)?;
94                    writer.write_all(val)?;
95                    Ok(TypeCode::Bin8)
96                }
97            }
98            ValueRef::Ubyte(val) => {
99                writer.write_u8(TypeCode::Ubyte as u8)?;
100                writer.write_u8(*val)?;
101                Ok(TypeCode::Ubyte)
102            }
103            ValueRef::Ushort(val) => {
104                writer.write_u8(TypeCode::Ushort as u8)?;
105                writer.write_u16::<NetworkEndian>(*val)?;
106                Ok(TypeCode::Ushort)
107            }
108            ValueRef::Uint(val) => {
109                if *val > U8_MAX as u32 {
110                    writer.write_u8(TypeCode::Uint as u8)?;
111                    writer.write_u32::<NetworkEndian>(*val)?;
112                    Ok(TypeCode::Uint)
113                } else if *val > 0 {
114                    writer.write_u8(TypeCode::Uintsmall as u8)?;
115                    writer.write_u8(*val as u8)?;
116                    Ok(TypeCode::Uintsmall)
117                } else {
118                    writer.write_u8(TypeCode::Uint0 as u8)?;
119                    Ok(TypeCode::Uint0)
120                }
121            }
122            ValueRef::Ulong(val) => {
123                if *val > U8_MAX as u64 {
124                    writer.write_u8(TypeCode::Ulong as u8)?;
125                    writer.write_u64::<NetworkEndian>(*val)?;
126                    Ok(TypeCode::Ulong)
127                } else if *val > 0 {
128                    writer.write_u8(TypeCode::Ulongsmall as u8)?;
129                    writer.write_u8(*val as u8)?;
130                    Ok(TypeCode::Ulongsmall)
131                } else {
132                    writer.write_u8(TypeCode::Ulong0 as u8)?;
133                    Ok(TypeCode::Ulong0)
134                }
135            }
136            ValueRef::Byte(val) => {
137                writer.write_u8(TypeCode::Byte as u8)?;
138                writer.write_i8(*val)?;
139                Ok(TypeCode::Byte)
140            }
141            ValueRef::Short(val) => {
142                writer.write_u8(TypeCode::Short as u8)?;
143                writer.write_i16::<NetworkEndian>(*val)?;
144                Ok(TypeCode::Short)
145            }
146            ValueRef::Int(val) => {
147                if *val > I8_MAX as i32 {
148                    writer.write_u8(TypeCode::Int as u8)?;
149                    writer.write_i32::<NetworkEndian>(*val)?;
150                    Ok(TypeCode::Int)
151                } else {
152                    writer.write_u8(TypeCode::Intsmall as u8)?;
153                    writer.write_i8(*val as i8)?;
154                    Ok(TypeCode::Intsmall)
155                }
156            }
157            ValueRef::Long(val) => {
158                if *val > I8_MAX as i64 {
159                    writer.write_u8(TypeCode::Long as u8)?;
160                    writer.write_i64::<NetworkEndian>(*val)?;
161                    Ok(TypeCode::Long)
162                } else {
163                    writer.write_u8(TypeCode::Longsmall as u8)?;
164                    writer.write_i8(*val as i8)?;
165                    Ok(TypeCode::Longsmall)
166                }
167            }
168            ValueRef::Array(vec) => {
169                let mut arraybuf = Vec::new();
170                let mut code = 0;
171                for v in vec.iter() {
172                    let mut valuebuf = Vec::new();
173                    v.encode(&mut valuebuf)?;
174                    if code == 0 {
175                        code = valuebuf[0];
176                    }
177                    arraybuf.extend_from_slice(&valuebuf[1..]);
178                }
179
180                if arraybuf.len() > LIST32_MAX {
181                    Err(AmqpError::decode_error(Some(
182                        "Encoded array size cannot be longer than 4294967291 bytes",
183                    )))
184                } else if arraybuf.len() > LIST8_MAX {
185                    writer.write_u8(TypeCode::Array32 as u8)?;
186                    writer.write_u32::<NetworkEndian>((5 + arraybuf.len()) as u32)?;
187                    writer.write_u32::<NetworkEndian>(vec.len() as u32)?;
188                    writer.write_u8(code)?;
189                    writer.write_all(&arraybuf[..])?;
190                    Ok(TypeCode::Array32)
191                } else if !arraybuf.is_empty() {
192                    writer.write_u8(TypeCode::Array8 as u8)?;
193                    writer.write_u8((2 + arraybuf.len()) as u8)?;
194                    writer.write_u8(vec.len() as u8)?;
195                    writer.write_u8(code)?;
196                    writer.write_all(&arraybuf[..])?;
197                    Ok(TypeCode::Array8)
198                } else {
199                    writer.write_u8(TypeCode::Null as u8)?;
200                    Ok(TypeCode::Null)
201                }
202            }
203            ValueRef::List(vec) => {
204                let mut listbuf = Vec::new();
205                for v in vec.iter() {
206                    v.encode(&mut listbuf)?;
207                }
208
209                if listbuf.len() > LIST32_MAX {
210                    Err(AmqpError::decode_error(Some(
211                        "Encoded list size cannot be longer than 4294967291 bytes",
212                    )))
213                } else if listbuf.len() > LIST8_MAX {
214                    writer.write_u8(TypeCode::List32 as u8)?;
215                    writer.write_u32::<NetworkEndian>((4 + listbuf.len()) as u32)?;
216                    writer.write_u32::<NetworkEndian>(vec.len() as u32)?;
217                    writer.write_all(&listbuf[..])?;
218                    Ok(TypeCode::List32)
219                } else if !listbuf.is_empty() {
220                    writer.write_u8(TypeCode::List8 as u8)?;
221                    writer.write_u8((1 + listbuf.len()) as u8)?;
222                    writer.write_u8(vec.len() as u8)?;
223                    writer.write_all(&listbuf[..])?;
224                    Ok(TypeCode::List8)
225                } else {
226                    writer.write_u8(TypeCode::List0 as u8)?;
227                    Ok(TypeCode::List0)
228                }
229            }
230            ValueRef::Map(m) => {
231                let mut listbuf = Vec::new();
232                for (key, value) in m {
233                    key.encode(&mut listbuf)?;
234                    value.encode(&mut listbuf)?;
235                }
236
237                let n_items = m.len() * 2;
238
239                if listbuf.len() > LIST32_MAX {
240                    Err(AmqpError::decode_error(Some(
241                        "Encoded map size cannot be longer than 4294967291 bytes",
242                    )))
243                } else if listbuf.len() > LIST8_MAX || n_items > U8_MAX {
244                    writer.write_u8(TypeCode::Map32 as u8)?;
245                    writer.write_u32::<NetworkEndian>((4 + listbuf.len()) as u32)?;
246                    writer.write_u32::<NetworkEndian>(n_items as u32)?;
247                    writer.write_all(&listbuf[..])?;
248                    Ok(TypeCode::Map32)
249                } else {
250                    writer.write_u8(TypeCode::Map8 as u8)?;
251                    writer.write_u8((1 + listbuf.len()) as u8)?;
252                    writer.write_u8(n_items as u8)?;
253                    writer.write_all(&listbuf[..])?;
254                    Ok(TypeCode::Map8)
255                }
256            }
257            ValueRef::ArrayRef(vec) => {
258                let mut arraybuf = Vec::new();
259                let mut code = 0;
260                for v in vec.iter() {
261                    let mut valuebuf = Vec::new();
262                    v.encode(&mut valuebuf)?;
263                    if code == 0 {
264                        code = valuebuf[0];
265                    }
266                    arraybuf.extend_from_slice(&valuebuf[1..]);
267                }
268
269                if arraybuf.len() > LIST32_MAX {
270                    Err(AmqpError::decode_error(Some(
271                        "Encoded array size cannot be longer than 4294967291 bytes",
272                    )))
273                } else if arraybuf.len() > LIST8_MAX {
274                    writer.write_u8(TypeCode::Array32 as u8)?;
275                    writer.write_u32::<NetworkEndian>((5 + arraybuf.len()) as u32)?;
276                    writer.write_u32::<NetworkEndian>(vec.len() as u32)?;
277                    writer.write_u8(code)?;
278                    writer.write_all(&arraybuf[..])?;
279                    Ok(TypeCode::Array32)
280                } else if !arraybuf.is_empty() {
281                    writer.write_u8(TypeCode::Array8 as u8)?;
282                    writer.write_u8((2 + arraybuf.len()) as u8)?;
283                    writer.write_u8(vec.len() as u8)?;
284                    writer.write_u8(code)?;
285                    writer.write_all(&arraybuf[..])?;
286                    Ok(TypeCode::Array8)
287                } else {
288                    writer.write_u8(TypeCode::Null as u8)?;
289                    Ok(TypeCode::Null)
290                }
291            }
292            ValueRef::ListRef(vec) => {
293                let mut listbuf = Vec::new();
294                for v in vec.iter() {
295                    v.encode(&mut listbuf)?;
296                }
297
298                if listbuf.len() > LIST32_MAX {
299                    Err(AmqpError::decode_error(Some(
300                        "Encoded list size cannot be longer than 4294967291 bytes",
301                    )))
302                } else if listbuf.len() > LIST8_MAX {
303                    writer.write_u8(TypeCode::List32 as u8)?;
304                    writer.write_u32::<NetworkEndian>((4 + listbuf.len()) as u32)?;
305                    writer.write_u32::<NetworkEndian>(vec.len() as u32)?;
306                    writer.write_all(&listbuf[..])?;
307                    Ok(TypeCode::List32)
308                } else if !listbuf.is_empty() {
309                    writer.write_u8(TypeCode::List8 as u8)?;
310                    writer.write_u8((1 + listbuf.len()) as u8)?;
311                    writer.write_u8(vec.len() as u8)?;
312                    writer.write_all(&listbuf[..])?;
313                    Ok(TypeCode::List8)
314                } else {
315                    writer.write_u8(TypeCode::List0 as u8)?;
316                    Ok(TypeCode::List0)
317                }
318            }
319            ValueRef::MapRef(m) => {
320                let mut listbuf = Vec::new();
321                for (key, value) in m {
322                    key.encode(&mut listbuf)?;
323                    value.encode(&mut listbuf)?;
324                }
325
326                let n_items = m.len() * 2;
327
328                if listbuf.len() > LIST32_MAX {
329                    Err(AmqpError::decode_error(Some(
330                        "Encoded map size cannot be longer than 4294967291 bytes",
331                    )))
332                } else if listbuf.len() > LIST8_MAX || n_items > U8_MAX {
333                    writer.write_u8(TypeCode::Map32 as u8)?;
334                    writer.write_u32::<NetworkEndian>((4 + listbuf.len()) as u32)?;
335                    writer.write_u32::<NetworkEndian>(n_items as u32)?;
336                    writer.write_all(&listbuf[..])?;
337                    Ok(TypeCode::Map32)
338                } else {
339                    writer.write_u8(TypeCode::Map8 as u8)?;
340                    writer.write_u8((1 + listbuf.len()) as u8)?;
341                    writer.write_u8(n_items as u8)?;
342                    writer.write_all(&listbuf[..])?;
343                    Ok(TypeCode::Map8)
344                }
345            }
346            ValueRef::Char(val) => {
347                writer.write_u8(TypeCode::Char as u8)?;
348                writer.write_u32::<NetworkEndian>(*val as u32)?;
349                Ok(TypeCode::Char)
350            }
351            ValueRef::Timestamp(val) => {
352                writer.write_u8(TypeCode::Timestamp as u8)?;
353                writer.write_u64::<NetworkEndian>(*val)?;
354                Ok(TypeCode::Timestamp)
355            }
356        }
357    }
358}
359
360impl Encoder for Timestamp {
361    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
362        Value::Timestamp(self.0).encode(writer)
363    }
364}
365
366impl Encoder for Value {
367    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
368        let value = self;
369        value.value_ref().encode(writer)
370    }
371}
372
373impl Encoder for ErrorCondition {
374    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
375        let mut encoder = FrameEncoder::new(DESC_ERROR);
376        encoder.encode_arg(&self.condition)?;
377        encoder.encode_arg(&self.description)?;
378        encoder.encode(writer)
379    }
380}
381
382/**
383 * Encoders for native rust types.
384 */
385impl Encoder for Vec<String> {
386    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
387        let mut values = Vec::new();
388        for s in self.iter() {
389            values.push(ValueRef::String(s));
390        }
391        ValueRef::ArrayRef(&values).encode(writer)
392    }
393}
394
395impl Encoder for Vec<u8> {
396    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
397        ValueRef::Binary(self).encode(writer)
398    }
399}
400
401impl Encoder for &[u8] {
402    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
403        ValueRef::Binary(self).encode(writer)
404    }
405}
406
407impl Encoder for String {
408    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
409        ValueRef::String(self).encode(writer)
410    }
411}
412
413impl Encoder for bool {
414    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
415        ValueRef::Bool(self).encode(writer)
416    }
417}
418
419impl Encoder for u64 {
420    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
421        ValueRef::Ulong(self).encode(writer)
422    }
423}
424
425impl Encoder for u32 {
426    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
427        ValueRef::Uint(self).encode(writer)
428    }
429}
430
431impl Encoder for u16 {
432    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
433        ValueRef::Ushort(self).encode(writer)
434    }
435}
436
437impl Encoder for u8 {
438    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
439        ValueRef::Ubyte(self).encode(writer)
440    }
441}
442
443impl<T: Encoder> Encoder for Option<T> {
444    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
445        match self {
446            Some(value) => value.encode(writer),
447            _ => Value::Null.encode(writer),
448        }
449    }
450}
451
452impl Encoder for Vec<(String, Value)> {
453    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
454        let m = self
455            .iter()
456            .map(|(k, v)| (ValueRef::String(k), v.value_ref()))
457            .collect();
458        ValueRef::MapRef(&m).encode(writer)
459    }
460}
461
462impl Encoder for Vec<(Value, Value)> {
463    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
464        let m = self
465            .iter()
466            .map(|(k, v)| (k.value_ref(), v.value_ref()))
467            .collect();
468        ValueRef::MapRef(&m).encode(writer)
469    }
470}
471
472impl Encoder for Vec<(Symbol, Value)> {
473    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
474        let m = self
475            .iter()
476            .map(|(k, v)| (ValueRef::from(k), v.value_ref()))
477            .collect();
478        ValueRef::MapRef(&m).encode(writer)
479    }
480}
481
482impl Encoder for BTreeMap<String, Value> {
483    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
484        let m = self
485            .iter()
486            .map(|(k, v)| (ValueRef::String(k), v.value_ref()))
487            .collect();
488        ValueRef::MapRef(&m).encode(writer)
489    }
490}
491
492impl Encoder for BTreeMap<Value, Value> {
493    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
494        let m = self
495            .iter()
496            .map(|(k, v)| (k.value_ref(), v.value_ref()))
497            .collect();
498        ValueRef::MapRef(&m).encode(writer)
499    }
500}
501
502impl Encoder for BTreeMap<Symbol, Value> {
503    fn encode(&self, writer: &mut dyn Write) -> Result<TypeCode> {
504        let m = self
505            .iter()
506            .map(|(k, v)| (ValueRef::from(k), v.value_ref()))
507            .collect();
508        ValueRef::MapRef(&m).encode(writer)
509    }
510}