ntex_amqp_codec/codec/
encode.rs

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