amqp_codec/codec/
encode.rs

1use std::collections::HashMap;
2use std::hash::{BuildHasher, Hash};
3use std::{i8, u8};
4
5use bytes::{BufMut, Bytes, BytesMut};
6use bytestring::ByteString;
7use chrono::{DateTime, Utc};
8use uuid::Uuid;
9
10use crate::codec::{self, ArrayEncode, Encode};
11use crate::framing::{self, AmqpFrame, SaslFrame};
12use crate::types::{
13    Descriptor, List, Multiple, StaticSymbol, Str, Symbol, Variant, VecStringMap, VecSymbolMap,
14};
15
16fn encode_null(buf: &mut BytesMut) {
17    buf.put_u8(codec::FORMATCODE_NULL);
18}
19
20pub trait FixedEncode {}
21
22impl<T: FixedEncode + ArrayEncode> Encode for T {
23    fn encoded_size(&self) -> usize {
24        self.array_encoded_size() + 1
25    }
26    fn encode(&self, buf: &mut BytesMut) {
27        buf.put_u8(T::ARRAY_FORMAT_CODE);
28        self.array_encode(buf);
29    }
30}
31
32impl Encode for bool {
33    fn encoded_size(&self) -> usize {
34        1
35    }
36    fn encode(&self, buf: &mut BytesMut) {
37        buf.put_u8(if *self {
38            codec::FORMATCODE_BOOLEAN_TRUE
39        } else {
40            codec::FORMATCODE_BOOLEAN_FALSE
41        });
42    }
43}
44impl ArrayEncode for bool {
45    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_BOOLEAN;
46    fn array_encoded_size(&self) -> usize {
47        1
48    }
49    fn array_encode(&self, buf: &mut BytesMut) {
50        buf.put_u8(if *self { 1 } else { 0 });
51    }
52}
53
54impl FixedEncode for u8 {}
55impl ArrayEncode for u8 {
56    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_UBYTE;
57    fn array_encoded_size(&self) -> usize {
58        1
59    }
60    fn array_encode(&self, buf: &mut BytesMut) {
61        buf.put_u8(*self);
62    }
63}
64
65impl FixedEncode for u16 {}
66impl ArrayEncode for u16 {
67    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_USHORT;
68    fn array_encoded_size(&self) -> usize {
69        2
70    }
71    fn array_encode(&self, buf: &mut BytesMut) {
72        buf.put_u16(*self);
73    }
74}
75
76impl Encode for u32 {
77    fn encoded_size(&self) -> usize {
78        if *self == 0 {
79            1
80        } else if *self > u32::from(u8::MAX) {
81            5
82        } else {
83            2
84        }
85    }
86    fn encode(&self, buf: &mut BytesMut) {
87        if *self == 0 {
88            buf.put_u8(codec::FORMATCODE_UINT_0)
89        } else if *self > u32::from(u8::MAX) {
90            buf.put_u8(codec::FORMATCODE_UINT);
91            buf.put_u32(*self);
92        } else {
93            buf.put_u8(codec::FORMATCODE_SMALLUINT);
94            buf.put_u8(*self as u8);
95        }
96    }
97}
98impl ArrayEncode for u32 {
99    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_UINT;
100    fn array_encoded_size(&self) -> usize {
101        4
102    }
103    fn array_encode(&self, buf: &mut BytesMut) {
104        buf.put_u32(*self);
105    }
106}
107
108impl Encode for u64 {
109    fn encoded_size(&self) -> usize {
110        if *self == 0 {
111            1
112        } else if *self > u64::from(u8::MAX) {
113            9
114        } else {
115            2
116        }
117    }
118
119    fn encode(&self, buf: &mut BytesMut) {
120        if *self == 0 {
121            buf.put_u8(codec::FORMATCODE_ULONG_0)
122        } else if *self > u64::from(u8::MAX) {
123            buf.put_u8(codec::FORMATCODE_ULONG);
124            buf.put_u64(*self);
125        } else {
126            buf.put_u8(codec::FORMATCODE_SMALLULONG);
127            buf.put_u8(*self as u8);
128        }
129    }
130}
131
132impl ArrayEncode for u64 {
133    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_ULONG;
134    fn array_encoded_size(&self) -> usize {
135        8
136    }
137    fn array_encode(&self, buf: &mut BytesMut) {
138        buf.put_u64(*self);
139    }
140}
141
142impl FixedEncode for i8 {}
143
144impl ArrayEncode for i8 {
145    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_BYTE;
146    fn array_encoded_size(&self) -> usize {
147        1
148    }
149    fn array_encode(&self, buf: &mut BytesMut) {
150        buf.put_i8(*self);
151    }
152}
153
154impl FixedEncode for i16 {}
155
156impl ArrayEncode for i16 {
157    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_SHORT;
158    fn array_encoded_size(&self) -> usize {
159        2
160    }
161    fn array_encode(&self, buf: &mut BytesMut) {
162        buf.put_i16(*self);
163    }
164}
165
166impl Encode for i32 {
167    fn encoded_size(&self) -> usize {
168        if *self > i32::from(i8::MAX) || *self < i32::from(i8::MIN) {
169            5
170        } else {
171            2
172        }
173    }
174
175    fn encode(&self, buf: &mut BytesMut) {
176        if *self > i32::from(i8::MAX) || *self < i32::from(i8::MIN) {
177            buf.put_u8(codec::FORMATCODE_INT);
178            buf.put_i32(*self);
179        } else {
180            buf.put_u8(codec::FORMATCODE_SMALLINT);
181            buf.put_i8(*self as i8);
182        }
183    }
184}
185
186impl ArrayEncode for i32 {
187    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_INT;
188
189    fn array_encoded_size(&self) -> usize {
190        4
191    }
192
193    fn array_encode(&self, buf: &mut BytesMut) {
194        buf.put_i32(*self);
195    }
196}
197
198impl Encode for i64 {
199    fn encoded_size(&self) -> usize {
200        if *self > i64::from(i8::MAX) || *self < i64::from(i8::MIN) {
201            9
202        } else {
203            2
204        }
205    }
206
207    fn encode(&self, buf: &mut BytesMut) {
208        if *self > i64::from(i8::MAX) || *self < i64::from(i8::MIN) {
209            buf.put_u8(codec::FORMATCODE_LONG);
210            buf.put_i64(*self);
211        } else {
212            buf.put_u8(codec::FORMATCODE_SMALLLONG);
213            buf.put_i8(*self as i8);
214        }
215    }
216}
217
218impl ArrayEncode for i64 {
219    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_LONG;
220    fn array_encoded_size(&self) -> usize {
221        8
222    }
223    fn array_encode(&self, buf: &mut BytesMut) {
224        buf.put_i64(*self);
225    }
226}
227
228impl FixedEncode for f32 {}
229
230impl ArrayEncode for f32 {
231    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_FLOAT;
232
233    fn array_encoded_size(&self) -> usize {
234        4
235    }
236
237    fn array_encode(&self, buf: &mut BytesMut) {
238        buf.put_f32(*self);
239    }
240}
241
242impl FixedEncode for f64 {}
243
244impl ArrayEncode for f64 {
245    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_DOUBLE;
246    fn array_encoded_size(&self) -> usize {
247        8
248    }
249    fn array_encode(&self, buf: &mut BytesMut) {
250        buf.put_f64(*self);
251    }
252}
253
254impl FixedEncode for char {}
255
256impl ArrayEncode for char {
257    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_CHAR;
258    fn array_encoded_size(&self) -> usize {
259        4
260    }
261    fn array_encode(&self, buf: &mut BytesMut) {
262        buf.put_u32(*self as u32);
263    }
264}
265
266impl FixedEncode for DateTime<Utc> {}
267
268impl ArrayEncode for DateTime<Utc> {
269    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_TIMESTAMP;
270    fn array_encoded_size(&self) -> usize {
271        8
272    }
273    fn array_encode(&self, buf: &mut BytesMut) {
274        let timestamp = self.timestamp() * 1000 + i64::from(self.timestamp_subsec_millis());
275        buf.put_i64(timestamp);
276    }
277}
278
279impl FixedEncode for Uuid {}
280
281impl ArrayEncode for Uuid {
282    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_UUID;
283    fn array_encoded_size(&self) -> usize {
284        16
285    }
286    fn array_encode(&self, buf: &mut BytesMut) {
287        buf.extend_from_slice(self.as_bytes());
288    }
289}
290
291impl Encode for Bytes {
292    fn encoded_size(&self) -> usize {
293        let length = self.len();
294        let size = if length > u8::MAX as usize { 5 } else { 2 };
295        size + length
296    }
297
298    fn encode(&self, buf: &mut BytesMut) {
299        let length = self.len();
300        if length > u8::MAX as usize {
301            buf.put_u8(codec::FORMATCODE_BINARY32);
302            buf.put_u32(length as u32);
303        } else {
304            buf.put_u8(codec::FORMATCODE_BINARY8);
305            buf.put_u8(length as u8);
306        }
307        buf.put_slice(self);
308    }
309}
310
311impl ArrayEncode for Bytes {
312    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_BINARY32;
313    fn array_encoded_size(&self) -> usize {
314        4 + self.len()
315    }
316    fn array_encode(&self, buf: &mut BytesMut) {
317        buf.put_u32(self.len() as u32);
318        buf.put_slice(&self);
319    }
320}
321
322impl Encode for ByteString {
323    fn encoded_size(&self) -> usize {
324        let length = self.len();
325        let size = if length > u8::MAX as usize { 5 } else { 2 };
326        size + length
327    }
328
329    fn encode(&self, buf: &mut BytesMut) {
330        let length = self.len();
331        if length > u8::MAX as usize {
332            buf.put_u8(codec::FORMATCODE_STRING32);
333            buf.put_u32(length as u32);
334        } else {
335            buf.put_u8(codec::FORMATCODE_STRING8);
336            buf.put_u8(length as u8);
337        }
338        buf.put_slice(self.as_bytes());
339    }
340}
341impl ArrayEncode for ByteString {
342    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_STRING32;
343    fn array_encoded_size(&self) -> usize {
344        4 + self.len()
345    }
346    fn array_encode(&self, buf: &mut BytesMut) {
347        buf.put_u32(self.len() as u32);
348        buf.put_slice(self.as_bytes());
349    }
350}
351
352impl Encode for str {
353    fn encoded_size(&self) -> usize {
354        let length = self.len();
355        let size = if length > u8::MAX as usize { 5 } else { 2 };
356        size + length
357    }
358
359    fn encode(&self, buf: &mut BytesMut) {
360        let length = self.len();
361        if length > u8::MAX as usize {
362            buf.put_u8(codec::FORMATCODE_STRING32);
363            buf.put_u32(length as u32);
364        } else {
365            buf.put_u8(codec::FORMATCODE_STRING8);
366            buf.put_u8(length as u8);
367        }
368        buf.put_slice(self.as_bytes());
369    }
370}
371
372impl ArrayEncode for str {
373    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_STRING32;
374    fn array_encoded_size(&self) -> usize {
375        4 + self.len()
376    }
377    fn array_encode(&self, buf: &mut BytesMut) {
378        buf.put_u32(self.len() as u32);
379        buf.put_slice(self.as_bytes());
380    }
381}
382
383impl Encode for Str {
384    fn encoded_size(&self) -> usize {
385        let length = self.len();
386        let size = if length > u8::MAX as usize { 5 } else { 2 };
387        size + length
388    }
389
390    fn encode(&self, buf: &mut BytesMut) {
391        let length = self.as_str().len();
392        if length > u8::MAX as usize {
393            buf.put_u8(codec::FORMATCODE_STRING32);
394            buf.put_u32(length as u32);
395        } else {
396            buf.put_u8(codec::FORMATCODE_STRING8);
397            buf.put_u8(length as u8);
398        }
399        buf.put_slice(self.as_bytes());
400    }
401}
402
403impl Encode for Symbol {
404    fn encoded_size(&self) -> usize {
405        let length = self.len();
406        let size = if length > u8::MAX as usize { 5 } else { 2 };
407        size + length
408    }
409
410    fn encode(&self, buf: &mut BytesMut) {
411        let length = self.as_str().len();
412        if length > u8::MAX as usize {
413            buf.put_u8(codec::FORMATCODE_SYMBOL32);
414            buf.put_u32(length as u32);
415        } else {
416            buf.put_u8(codec::FORMATCODE_SYMBOL8);
417            buf.put_u8(length as u8);
418        }
419        buf.put_slice(self.as_bytes());
420    }
421}
422
423impl ArrayEncode for Symbol {
424    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_SYMBOL32;
425    fn array_encoded_size(&self) -> usize {
426        4 + self.len()
427    }
428    fn array_encode(&self, buf: &mut BytesMut) {
429        buf.put_u32(self.len() as u32);
430        buf.put_slice(self.as_bytes());
431    }
432}
433
434impl Encode for StaticSymbol {
435    fn encoded_size(&self) -> usize {
436        let length = self.0.len();
437        let size = if length > u8::MAX as usize { 5 } else { 2 };
438        size + length
439    }
440
441    fn encode(&self, buf: &mut BytesMut) {
442        let length = self.0.len();
443        if length > u8::MAX as usize {
444            buf.put_u8(codec::FORMATCODE_SYMBOL32);
445            buf.put_u32(length as u32);
446        } else {
447            buf.put_u8(codec::FORMATCODE_SYMBOL8);
448            buf.put_u8(length as u8);
449        }
450        buf.put_slice(self.0.as_bytes());
451    }
452}
453
454fn map_encoded_size<K: Hash + Eq + Encode, V: Encode, S: BuildHasher>(
455    map: &HashMap<K, V, S>,
456) -> usize {
457    map.iter()
458        .fold(0, |r, (k, v)| r + k.encoded_size() + v.encoded_size())
459}
460impl<K: Eq + Hash + Encode, V: Encode, S: BuildHasher> Encode for HashMap<K, V, S> {
461    fn encoded_size(&self) -> usize {
462        let size = map_encoded_size(self);
463        // f:1 + s:4 + c:4 vs f:1 + s:1 + c:1
464        let preamble = if size + 1 > u8::MAX as usize { 9 } else { 3 };
465        preamble + size
466    }
467
468    fn encode(&self, buf: &mut BytesMut) {
469        let count = self.len() * 2; // key-value pair accounts for two items in count
470        let size = map_encoded_size(self);
471        if size + 1 > u8::MAX as usize {
472            buf.put_u8(codec::FORMATCODE_MAP32);
473            buf.put_u32((size + 4) as u32); // +4 for 4 byte count that follows
474            buf.put_u32(count as u32);
475        } else {
476            buf.put_u8(codec::FORMATCODE_MAP8);
477            buf.put_u8((size + 1) as u8); // +1 for 1 byte count that follows
478            buf.put_u8(count as u8);
479        }
480
481        for (k, v) in self {
482            k.encode(buf);
483            v.encode(buf);
484        }
485    }
486}
487
488impl<K: Eq + Hash + Encode, V: Encode> ArrayEncode for HashMap<K, V> {
489    const ARRAY_FORMAT_CODE: u8 = codec::FORMATCODE_MAP32;
490    fn array_encoded_size(&self) -> usize {
491        8 + map_encoded_size(self)
492    }
493    fn array_encode(&self, buf: &mut BytesMut) {
494        let count = self.len() * 2;
495        let size = map_encoded_size(self) + 4;
496        buf.put_u32(size as u32);
497        buf.put_u32(count as u32);
498
499        for (k, v) in self {
500            k.encode(buf);
501            v.encode(buf);
502        }
503    }
504}
505
506impl Encode for VecSymbolMap {
507    fn encoded_size(&self) -> usize {
508        let size = self
509            .0
510            .iter()
511            .fold(0, |r, (k, v)| r + k.encoded_size() + v.encoded_size());
512
513        // f:1 + s:4 + c:4 vs f:1 + s:1 + c:1
514        let preamble = if size + 1 > u8::MAX as usize { 9 } else { 3 };
515        preamble + size
516    }
517
518    fn encode(&self, buf: &mut BytesMut) {
519        let count = self.len() * 2; // key-value pair accounts for two items in count
520        let size = self
521            .0
522            .iter()
523            .fold(0, |r, (k, v)| r + k.encoded_size() + v.encoded_size());
524
525        if size + 1 > u8::MAX as usize {
526            buf.put_u8(codec::FORMATCODE_MAP32);
527            buf.put_u32((size + 4) as u32); // +4 for 4 byte count that follows
528            buf.put_u32(count as u32);
529        } else {
530            buf.put_u8(codec::FORMATCODE_MAP8);
531            buf.put_u8((size + 1) as u8); // +1 for 1 byte count that follows
532            buf.put_u8(count as u8);
533        }
534
535        for (k, v) in self.iter() {
536            k.encode(buf);
537            v.encode(buf);
538        }
539    }
540}
541
542impl Encode for VecStringMap {
543    fn encoded_size(&self) -> usize {
544        let size = self
545            .0
546            .iter()
547            .fold(0, |r, (k, v)| r + k.encoded_size() + v.encoded_size());
548
549        // f:1 + s:4 + c:4 vs f:1 + s:1 + c:1
550        let preamble = if size + 1 > u8::MAX as usize { 9 } else { 3 };
551        preamble + size
552    }
553
554    fn encode(&self, buf: &mut BytesMut) {
555        let count = self.len() * 2; // key-value pair accounts for two items in count
556        let size = self
557            .0
558            .iter()
559            .fold(0, |r, (k, v)| r + k.encoded_size() + v.encoded_size());
560
561        if size + 1 > u8::MAX as usize {
562            buf.put_u8(codec::FORMATCODE_MAP32);
563            buf.put_u32((size + 4) as u32); // +4 for 4 byte count that follows
564            buf.put_u32(count as u32);
565        } else {
566            buf.put_u8(codec::FORMATCODE_MAP8);
567            buf.put_u8((size + 1) as u8); // +1 for 1 byte count that follows
568            buf.put_u8(count as u8);
569        }
570
571        for (k, v) in self.iter() {
572            k.encode(buf);
573            v.encode(buf);
574        }
575    }
576}
577
578fn array_encoded_size<T: ArrayEncode>(vec: &[T]) -> usize {
579    vec.iter().fold(0, |r, i| r + i.array_encoded_size())
580}
581
582impl<T: ArrayEncode> Encode for Vec<T> {
583    fn encoded_size(&self) -> usize {
584        let content_size = array_encoded_size(self);
585        // format_code + size + count + item constructor -- todo: support described ctor?
586        (if content_size + 1 > u8::MAX as usize {
587            10
588        } else {
589            4
590        }) // +1 for 1 byte count and 1 byte format code
591            + content_size
592    }
593
594    fn encode(&self, buf: &mut BytesMut) {
595        let size = array_encoded_size(self);
596        if size + 1 > u8::MAX as usize {
597            buf.put_u8(codec::FORMATCODE_ARRAY32);
598            buf.put_u32((size + 5) as u32); // +4 for 4 byte count and 1 byte item ctor that follow
599            buf.put_u32(self.len() as u32);
600        } else {
601            buf.put_u8(codec::FORMATCODE_ARRAY8);
602            buf.put_u8((size + 2) as u8); // +1 for 1 byte count and 1 byte item ctor that follow
603            buf.put_u8(self.len() as u8);
604        }
605        buf.put_u8(T::ARRAY_FORMAT_CODE);
606        for i in self {
607            i.array_encode(buf);
608        }
609    }
610}
611
612impl<T: Encode + ArrayEncode> Encode for Multiple<T> {
613    fn encoded_size(&self) -> usize {
614        let count = self.len();
615        if count == 1 {
616            // special case: single item is encoded without array encoding
617            self.0[0].encoded_size()
618        } else {
619            self.0.encoded_size()
620        }
621    }
622
623    fn encode(&self, buf: &mut BytesMut) {
624        let count = self.0.len();
625        if count == 1 {
626            // special case: single item is encoded without array encoding
627            self.0[0].encode(buf)
628        } else {
629            self.0.encode(buf)
630        }
631    }
632}
633
634fn list_encoded_size(vec: &List) -> usize {
635    vec.iter().fold(0, |r, i| r + i.encoded_size())
636}
637
638impl Encode for List {
639    fn encoded_size(&self) -> usize {
640        let content_size = list_encoded_size(self);
641        // format_code + size + count
642        (if content_size + 1 > u8::MAX as usize {
643            9
644        } else {
645            3
646        }) + content_size
647    }
648
649    fn encode(&self, buf: &mut BytesMut) {
650        let size = list_encoded_size(self);
651        if size + 1 > u8::MAX as usize {
652            buf.put_u8(codec::FORMATCODE_ARRAY32);
653            buf.put_u32((size + 4) as u32); // +4 for 4 byte count that follow
654            buf.put_u32(self.len() as u32);
655        } else {
656            buf.put_u8(codec::FORMATCODE_ARRAY8);
657            buf.put_u8((size + 1) as u8); // +1 for 1 byte count that follow
658            buf.put_u8(self.len() as u8);
659        }
660        for i in self.iter() {
661            i.encode(buf);
662        }
663    }
664}
665
666impl Encode for Variant {
667    fn encoded_size(&self) -> usize {
668        match *self {
669            Variant::Null => 1,
670            Variant::Boolean(b) => b.encoded_size(),
671            Variant::Ubyte(b) => b.encoded_size(),
672            Variant::Ushort(s) => s.encoded_size(),
673            Variant::Uint(i) => i.encoded_size(),
674            Variant::Ulong(l) => l.encoded_size(),
675            Variant::Byte(b) => b.encoded_size(),
676            Variant::Short(s) => s.encoded_size(),
677            Variant::Int(i) => i.encoded_size(),
678            Variant::Long(l) => l.encoded_size(),
679            Variant::Float(f) => f.encoded_size(),
680            Variant::Double(d) => d.encoded_size(),
681            Variant::Char(c) => c.encoded_size(),
682            Variant::Timestamp(ref t) => t.encoded_size(),
683            Variant::Uuid(ref u) => u.encoded_size(),
684            Variant::Binary(ref b) => b.encoded_size(),
685            Variant::String(ref s) => s.encoded_size(),
686            Variant::Symbol(ref s) => s.encoded_size(),
687            Variant::StaticSymbol(ref s) => s.encoded_size(),
688            Variant::List(ref l) => l.encoded_size(),
689            Variant::Map(ref m) => m.map.encoded_size(),
690            Variant::Described(ref dv) => dv.0.encoded_size() + dv.1.encoded_size(),
691        }
692    }
693
694    /// Encodes `Variant` into provided `BytesMut`
695    fn encode(&self, buf: &mut BytesMut) {
696        match *self {
697            Variant::Null => encode_null(buf),
698            Variant::Boolean(b) => b.encode(buf),
699            Variant::Ubyte(b) => b.encode(buf),
700            Variant::Ushort(s) => s.encode(buf),
701            Variant::Uint(i) => i.encode(buf),
702            Variant::Ulong(l) => l.encode(buf),
703            Variant::Byte(b) => b.encode(buf),
704            Variant::Short(s) => s.encode(buf),
705            Variant::Int(i) => i.encode(buf),
706            Variant::Long(l) => l.encode(buf),
707            Variant::Float(f) => f.encode(buf),
708            Variant::Double(d) => d.encode(buf),
709            Variant::Char(c) => c.encode(buf),
710            Variant::Timestamp(ref t) => t.encode(buf),
711            Variant::Uuid(ref u) => u.encode(buf),
712            Variant::Binary(ref b) => b.encode(buf),
713            Variant::String(ref s) => s.encode(buf),
714            Variant::Symbol(ref s) => s.encode(buf),
715            Variant::StaticSymbol(ref s) => s.encode(buf),
716            Variant::List(ref l) => l.encode(buf),
717            Variant::Map(ref m) => m.map.encode(buf),
718            Variant::Described(ref dv) => {
719                dv.0.encode(buf);
720                dv.1.encode(buf);
721            }
722        }
723    }
724}
725
726impl<T: Encode> Encode for Option<T> {
727    fn encoded_size(&self) -> usize {
728        self.as_ref().map_or(1, |v| v.encoded_size())
729    }
730
731    fn encode(&self, buf: &mut BytesMut) {
732        match *self {
733            Some(ref e) => e.encode(buf),
734            None => encode_null(buf),
735        }
736    }
737}
738
739impl Encode for Descriptor {
740    fn encoded_size(&self) -> usize {
741        match *self {
742            Descriptor::Ulong(v) => 1 + v.encoded_size(),
743            Descriptor::Symbol(ref v) => 1 + v.encoded_size(),
744        }
745    }
746
747    fn encode(&self, buf: &mut BytesMut) {
748        buf.put_u8(codec::FORMATCODE_DESCRIBED);
749        match *self {
750            Descriptor::Ulong(v) => v.encode(buf),
751            Descriptor::Symbol(ref v) => v.encode(buf),
752        }
753    }
754}
755
756const WORD_LEN: usize = 4;
757
758impl Encode for AmqpFrame {
759    fn encoded_size(&self) -> usize {
760        framing::HEADER_LEN + self.performative().encoded_size()
761    }
762
763    fn encode(&self, buf: &mut BytesMut) {
764        let doff: u8 = (framing::HEADER_LEN / WORD_LEN) as u8;
765        buf.put_u32(self.encoded_size() as u32);
766        buf.put_u8(doff);
767        buf.put_u8(framing::FRAME_TYPE_AMQP);
768        buf.put_u16(self.channel_id());
769        self.performative().encode(buf);
770    }
771}
772
773impl Encode for SaslFrame {
774    fn encoded_size(&self) -> usize {
775        framing::HEADER_LEN + self.body.encoded_size()
776    }
777
778    fn encode(&self, buf: &mut BytesMut) {
779        let doff: u8 = (framing::HEADER_LEN / WORD_LEN) as u8;
780        buf.put_u32(self.encoded_size() as u32);
781        buf.put_u8(doff);
782        buf.put_u8(framing::FRAME_TYPE_SASL);
783        buf.put_u16(0);
784        self.body.encode(buf);
785    }
786}