Skip to main content

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, Composite, Encode};
8use crate::framing::{self, AmqpFrame, SaslFrame};
9use crate::types::{
10    Constructor, Descriptor, List, ListDescribed, Multiple, StaticSymbol, Str, Symbol, Variant,
11    VecStringMap, 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
628impl Encode for List {
629    fn encoded_size(&self) -> usize {
630        let content_size = self.iter().fold(0, |r, i| r + i.encoded_size());
631        // format_code + size + count
632        (if content_size + 1 > u8::MAX as usize {
633            9
634        } else {
635            3
636        }) + content_size
637    }
638
639    fn encode(&self, buf: &mut BytesMut) {
640        let size = self.iter().fold(0, |r, i| r + i.encoded_size());
641        if size + 1 > u8::MAX as usize {
642            buf.put_u8(codec::FORMATCODE_LIST32);
643            buf.put_u32((size + 4) as u32); // +4 for 4 byte count that follow
644            buf.put_u32(self.len() as u32);
645        } else {
646            buf.put_u8(codec::FORMATCODE_LIST8);
647            buf.put_u8((size + 1) as u8); // +1 for 1 byte count that follow
648            buf.put_u8(self.len() as u8);
649        }
650        for i in self.iter() {
651            i.encode(buf);
652        }
653    }
654}
655
656impl<T: Composite> Encode for ListDescribed<T> {
657    fn encoded_size(&self) -> usize {
658        let descr_size = T::descriptor().encoded_size();
659        let content_size = self
660            .iter()
661            .fold(0, |r, i| r + i.encoded_size() + descr_size);
662
663        // format_code + size + count
664        (if content_size + 1 > u8::MAX as usize {
665            9
666        } else {
667            3
668        }) + content_size
669    }
670
671    fn encode(&self, buf: &mut BytesMut) {
672        let descr = T::descriptor();
673        let descr_size = descr.encoded_size();
674        let content_size = self
675            .iter()
676            .fold(0, |r, i| r + i.encoded_size() + descr_size);
677
678        if content_size + 1 > u8::MAX as usize {
679            buf.put_u8(codec::FORMATCODE_LIST32);
680            buf.put_u32((content_size + 4) as u32); // +4 for 4 byte count that follow
681            buf.put_u32(self.len() as u32);
682        } else {
683            buf.put_u8(codec::FORMATCODE_LIST8);
684            buf.put_u8((content_size + 1) as u8); // +1 for 1 byte count that follow
685            buf.put_u8(self.len() as u8);
686        }
687        for i in self.iter() {
688            descr.encode(buf);
689            i.encode(buf);
690        }
691    }
692}
693
694impl Encode for Variant {
695    fn encoded_size(&self) -> usize {
696        match *self {
697            Variant::Null => 1,
698            Variant::Boolean(b) => b.encoded_size(),
699            Variant::Ubyte(b) => b.encoded_size(),
700            Variant::Ushort(s) => s.encoded_size(),
701            Variant::Uint(i) => i.encoded_size(),
702            Variant::Ulong(l) => l.encoded_size(),
703            Variant::Byte(b) => b.encoded_size(),
704            Variant::Short(s) => s.encoded_size(),
705            Variant::Int(i) => i.encoded_size(),
706            Variant::Long(l) => l.encoded_size(),
707            Variant::Float(f) => f.encoded_size(),
708            Variant::Double(d) => d.encoded_size(),
709            Variant::Decimal32(_) => 1 + 4,
710            Variant::Decimal64(_) => 1 + 8,
711            Variant::Decimal128(_) => 1 + 16,
712            Variant::Char(c) => c.encoded_size(),
713            Variant::Timestamp(ref t) => t.encoded_size(),
714            Variant::Uuid(ref u) => u.encoded_size(),
715            Variant::Binary(ref b) => b.encoded_size(),
716            Variant::String(ref s) => s.encoded_size(),
717            Variant::Symbol(ref s) => s.encoded_size(),
718            Variant::List(ref l) => l.encoded_size(),
719            Variant::Array(ref a) => a.encoded_size(),
720            Variant::Map(ref m) => m.map.encoded_size(),
721            Variant::Described(ref dv) => dv.0.encoded_size() + dv.1.encoded_size(),
722            Variant::DescribedCompound(ref described) => described.encoded_size(),
723        }
724    }
725
726    /// Encodes `Variant` into provided `BytesMut`
727    fn encode(&self, buf: &mut BytesMut) {
728        match *self {
729            Variant::Null => encode_null(buf),
730            Variant::Boolean(b) => b.encode(buf),
731            Variant::Ubyte(b) => b.encode(buf),
732            Variant::Ushort(s) => s.encode(buf),
733            Variant::Uint(i) => i.encode(buf),
734            Variant::Ulong(l) => l.encode(buf),
735            Variant::Byte(b) => b.encode(buf),
736            Variant::Short(s) => s.encode(buf),
737            Variant::Int(i) => i.encode(buf),
738            Variant::Long(l) => l.encode(buf),
739            Variant::Float(f) => f.encode(buf),
740            Variant::Double(d) => d.encode(buf),
741            Variant::Decimal32(ref data) => {
742                buf.put_u8(codec::FORMATCODE_DECIMAL32);
743                buf.extend_from_slice(data.as_ref());
744            }
745            Variant::Decimal64(ref data) => {
746                buf.put_u8(codec::FORMATCODE_DECIMAL64);
747                buf.extend_from_slice(data.as_ref());
748            }
749            Variant::Decimal128(ref data) => {
750                buf.put_u8(codec::FORMATCODE_DECIMAL128);
751                buf.extend_from_slice(data.as_ref());
752            }
753            Variant::Char(c) => c.encode(buf),
754            Variant::Timestamp(ref t) => t.encode(buf),
755            Variant::Uuid(ref u) => u.encode(buf),
756            Variant::Binary(ref b) => b.encode(buf),
757            Variant::String(ref s) => s.encode(buf),
758            Variant::Symbol(ref s) => s.encode(buf),
759            Variant::List(ref l) => l.encode(buf),
760            Variant::Map(ref m) => m.map.encode(buf),
761            Variant::Array(ref a) => a.encode(buf),
762            Variant::Described(ref dv) => {
763                dv.0.encode(buf);
764                dv.1.encode(buf);
765            }
766            Variant::DescribedCompound(ref described) => described.encode(buf),
767        }
768    }
769}
770
771impl<T: Encode> Encode for Option<T> {
772    fn encoded_size(&self) -> usize {
773        self.as_ref().map_or(1, |v| v.encoded_size())
774    }
775
776    fn encode(&self, buf: &mut BytesMut) {
777        match *self {
778            Some(ref e) => e.encode(buf),
779            None => encode_null(buf),
780        }
781    }
782}
783
784impl Encode for Descriptor {
785    fn encoded_size(&self) -> usize {
786        // 1 for described type's format code (0x00) + size of the descriptor value itself
787        1 + match *self {
788            Descriptor::Ulong(v) => v.encoded_size(),
789            Descriptor::Symbol(ref v) => v.encoded_size(),
790        }
791    }
792
793    fn encode(&self, buf: &mut BytesMut) {
794        buf.put_u8(codec::FORMATCODE_DESCRIBED);
795        match *self {
796            Descriptor::Ulong(v) => v.encode(buf),
797            Descriptor::Symbol(ref v) => v.encode(buf),
798        }
799    }
800}
801
802impl Encode for Constructor {
803    fn encoded_size(&self) -> usize {
804        match self {
805            Constructor::FormatCode(_) => 1,
806            Constructor::Described {
807                descriptor,
808                format_code: _,
809            } => 1 + descriptor.encoded_size(),
810        }
811    }
812
813    fn encode(&self, buf: &mut BytesMut) {
814        match self {
815            Constructor::FormatCode(format_code) => buf.put_u8(*format_code),
816            Constructor::Described {
817                descriptor,
818                format_code,
819            } => {
820                descriptor.encode(buf);
821                buf.put_u8(*format_code);
822            }
823        }
824    }
825}
826
827const WORD_LEN: usize = 4;
828
829impl Encode for AmqpFrame {
830    fn encoded_size(&self) -> usize {
831        framing::HEADER_LEN + self.performative().encoded_size()
832    }
833
834    fn encode(&self, buf: &mut BytesMut) {
835        let doff: u8 = (framing::HEADER_LEN / WORD_LEN) as u8;
836        buf.put_u32(self.encoded_size() as u32);
837        buf.put_u8(doff);
838        buf.put_u8(framing::FRAME_TYPE_AMQP);
839        buf.put_u16(self.channel_id());
840        self.performative().encode(buf);
841    }
842}
843
844impl Encode for SaslFrame {
845    fn encoded_size(&self) -> usize {
846        framing::HEADER_LEN + self.body.encoded_size()
847    }
848
849    fn encode(&self, buf: &mut BytesMut) {
850        let doff: u8 = (framing::HEADER_LEN / WORD_LEN) as u8;
851        buf.put_u32(self.encoded_size() as u32);
852        buf.put_u8(doff);
853        buf.put_u8(framing::FRAME_TYPE_SASL);
854        buf.put_u16(0);
855        self.body.encode(buf);
856    }
857}