1use bytes::{BufMut, Bytes, BytesMut};
2use errors::EncodeErr;
3use std::collections::BTreeMap;
4use std::convert::TryFrom;
5use std::mem;
6use tars_trait::{EnumToI32, StructToTars};
7use tars_type::TarsTypeMark::*;
8use tars_type::*;
9
10const MAX_HEADER_LEN: usize = 2;
11const MAX_SIZE_LEN: usize = 4;
12
13#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
14pub struct TarsEncoder {
15 buf: BytesMut,
16}
17
18impl TarsEncoder {
19 pub fn new() -> Self {
20 TarsEncoder {
21 buf: BytesMut::new(),
22 }
23 }
24
25 pub fn individual_encode<T>(ele: &T) -> Result<Bytes, EncodeErr>
26 where
27 T: EncodeTars,
28 {
29 let mut encoder = TarsEncoder::new();
30 ele._encode(&mut encoder, 0)?;
31 Ok(encoder.to_bytes())
32 }
33
34 pub fn to_bytes(self) -> Bytes {
36 self.buf.freeze()
37 }
38
39 pub fn to_bytes_mut(self) -> BytesMut {
40 self.buf
41 }
42
43 pub fn check_maybe_resize(&mut self, len: usize) {
44 if self.buf.remaining_mut() < len {
45 let new_len = self.buf.remaining_mut() + len + 1024;
46 self.buf.reserve(new_len)
47 }
48 }
49
50 fn put_head(&mut self, tag: u8, tars_type: TarsTypeMark) -> Result<(), EncodeErr> {
51 self.check_maybe_resize(MAX_HEADER_LEN);
52 if tag > u8::max_value() {
53 Err(EncodeErr::TooBigTagErr)
54 } else {
55 if tag < 15 {
56 let head = (tag << 4) | tars_type.value();
57 self.buf.put_u8(head);
58 } else {
59 let head: u16 = u16::from((0xF0u8) | tars_type.value()) << 8 | u16::from(tag);
60 self.buf.put_u16_be(head)
61 }
62 Ok(())
63 }
64 }
65}
66
67pub trait TarsEncoderNormalTrait {
70 fn write_int8(&mut self, tag: u8, ele: i8) -> Result<(), EncodeErr>;
71 fn write_boolean(&mut self, tag: u8, ele: bool) -> Result<(), EncodeErr>;
72
73 fn write_int16(&mut self, tag: u8, ele: i16) -> Result<(), EncodeErr>;
74 fn write_int32(&mut self, tag: u8, ele: i32) -> Result<(), EncodeErr>;
75 fn write_int64(&mut self, tag: u8, ele: i64) -> Result<(), EncodeErr>;
76
77 fn write_uint8(&mut self, tag: u8, ele: u8) -> Result<(), EncodeErr>;
78 fn write_uint16(&mut self, tag: u8, ele: u16) -> Result<(), EncodeErr>;
79 fn write_uint32(&mut self, tag: u8, ele: u32) -> Result<(), EncodeErr>;
80
81 fn write_float(&mut self, tag: u8, ele: f32) -> Result<(), EncodeErr>;
82 fn write_double(&mut self, tag: u8, ele: f64) -> Result<(), EncodeErr>;
83
84 fn write_string(&mut self, tag: u8, ele: &String) -> Result<(), EncodeErr>;
85
86 fn write_bytes(&mut self, tag: u8, ele: &Bytes) -> Result<(), EncodeErr>;
87
88 fn write_map<K, V>(&mut self, tag: u8, ele: &BTreeMap<K, V>) -> Result<(), EncodeErr>
89 where
90 K: EncodeTars + Ord,
91 V: EncodeTars;
92
93 fn write_enum<T>(&mut self, tag: u8, ele: &T) -> Result<(), EncodeErr>
94 where
95 T: EnumToI32;
96
97 fn write_struct<T>(&mut self, tag: u8, ele: &T) -> Result<(), EncodeErr>
98 where
99 T: StructToTars;
100}
101
102pub trait TarsEncodeListTrait<T>
103where
104 T: EncodeTars,
105{
106 fn write_list(&mut self, tag: u8, ele: &Vec<T>) -> Result<(), EncodeErr>;
107}
108
109impl TarsEncoderNormalTrait for TarsEncoder {
110 fn write_int8(&mut self, tag: u8, ele: i8) -> Result<(), EncodeErr> {
111 if ele == 0 {
112 self.put_head(tag, EnZero)
113 } else {
114 self.put_head(tag, EnInt8)?;
115 self.check_maybe_resize(mem::size_of::<i8>());
116 self.buf.put_i8(ele);
117 Ok(())
118 }
119 }
120
121 fn write_boolean(&mut self, tag: u8, ele: bool) -> Result<(), EncodeErr> {
122 self.write_int8(tag, ele as i8)
123 }
124
125 fn write_int16(&mut self, tag: u8, ele: i16) -> Result<(), EncodeErr> {
126 if ele >= i16::from(i8::min_value()) && ele <= i16::from(i8::max_value()) {
127 self.write_int8(tag, ele as i8)
128 } else {
129 self.put_head(tag, EnInt16)?;
130 self.check_maybe_resize(mem::size_of::<i16>());
131 self.buf.put_i16_be(ele);
132 Ok(())
133 }
134 }
135
136 fn write_int32(&mut self, tag: u8, ele: i32) -> Result<(), EncodeErr> {
137 if ele >= i32::from(i16::min_value()) && ele <= i32::from(i16::max_value()) {
138 self.write_int16(tag, ele as i16)
139 } else {
140 self.put_head(tag, EnInt32)?;
141 self.check_maybe_resize(mem::size_of::<i32>());
142 self.buf.put_i32_be(ele);
143 Ok(())
144 }
145 }
146
147 fn write_int64(&mut self, tag: u8, ele: i64) -> Result<(), EncodeErr> {
148 if ele >= i64::from(i32::min_value()) && ele <= i64::from(i32::max_value()) {
149 self.write_int32(tag, ele as i32)
150 } else {
151 self.put_head(tag, EnInt64)?;
152 self.check_maybe_resize(mem::size_of::<i64>());
153 self.buf.put_i64_be(ele);
154 Ok(())
155 }
156 }
157
158 fn write_uint8(&mut self, tag: u8, ele: u8) -> Result<(), EncodeErr> {
159 self.write_int16(tag, ele as i16)
160 }
161
162 fn write_uint16(&mut self, tag: u8, ele: u16) -> Result<(), EncodeErr> {
163 self.write_int32(tag, ele as i32)
164 }
165
166 fn write_uint32(&mut self, tag: u8, ele: u32) -> Result<(), EncodeErr> {
167 self.write_int64(tag, ele as i64)
168 }
169
170 fn write_float(&mut self, tag: u8, ele: f32) -> Result<(), EncodeErr> {
171 if ele == 0.0 {
172 self.put_head(tag, EnZero)?;
173 } else {
174 self.put_head(tag, EnFloat)?;
175 self.check_maybe_resize(mem::size_of::<f32>());
176 self.buf.put_f32_be(ele)
177 }
178 Ok(())
179 }
180 fn write_double(&mut self, tag: u8, ele: f64) -> Result<(), EncodeErr> {
181 if ele == 0.0 {
182 self.put_head(tag, EnZero)?;
183 } else {
184 self.put_head(tag, EnDouble)?;
185 self.check_maybe_resize(mem::size_of::<f64>());
186 self.buf.put_f64_be(ele)
187 }
188 Ok(())
189 }
190 fn write_string(&mut self, tag: u8, ele: &String) -> Result<(), EncodeErr> {
191 let len = ele.len();
192 self.check_maybe_resize(MAX_SIZE_LEN + len);
193
194 if len <= usize::from(u8::max_value()) {
195 self.put_head(tag, EnString1)?;
197 match u8::try_from(len) {
198 Ok(l) => {
199 self.buf.put_u8(l);
200 self.buf.put(ele);
201 Ok(())
202 }
203 Err(_) => Err(EncodeErr::ConvertU8Err),
204 }
205 } else if len <= u32::max_value() as usize {
206 self.put_head(tag, EnString4)?;
208 self.buf.put_u32_be(len as u32);
209 self.buf.put(ele);
210 Ok(())
211 } else {
212 Err(EncodeErr::DataTooBigErr)
213 }
214 }
215
216 fn write_bytes(&mut self, tag: u8, ele: &Bytes) -> Result<(), EncodeErr> {
217 let len = ele.len();
218 if len > i32::max_value() as usize {
219 Err(EncodeErr::DataTooBigErr)
220 } else {
221 self.put_head(tag, EnSimplelist)?;
222 self.put_head(0, EnInt8)?;
223 self.write_int32(0, len as i32)?;
224 self.buf.extend_from_slice(ele);
225 Ok(())
226 }
227 }
228
229 fn write_map<K, V>(&mut self, tag: u8, ele: &BTreeMap<K, V>) -> Result<(), EncodeErr>
230 where
231 K: EncodeTars + Ord,
232 V: EncodeTars,
233 {
234 let len = ele.len();
235 if len > i32::max_value() as usize {
236 Err(EncodeErr::DataTooBigErr)
237 } else {
238 self.put_head(tag, EnMaps)?;
239 self.write_int32(0, len as i32)?;
240 for (key, value) in ele.iter() {
241 key._encode(self, 0)?;
242 value._encode(self, 1)?;
243 }
244 Ok(())
245 }
246 }
247
248 fn write_enum<T>(&mut self, tag: u8, ele: &T) -> Result<(), EncodeErr>
249 where
250 T: EnumToI32,
251 {
252 self.write_int32(tag, ele._to_i32())
253 }
254
255 fn write_struct<T>(&mut self, tag: u8, ele: &T) -> Result<(), EncodeErr>
256 where
257 T: StructToTars,
258 {
259 self.put_head(tag, EnStructBegin)?;
260 ele._encode_to(self)?;
261 self.put_head(0, EnStructEnd)
262 }
263}
264
265impl<T> TarsEncodeListTrait<T> for TarsEncoder
266where
267 T: EncodeTars,
268{
269 default fn write_list(&mut self, tag: u8, ele: &Vec<T>) -> Result<(), EncodeErr> {
270 let len = ele.len();
271 if len > i32::max_value() as usize {
272 Err(EncodeErr::DataTooBigErr)
273 } else {
274 self.put_head(tag, EnList)?;
275 self.write_int32(0, len as i32)?;
276 for ele in ele.into_iter() {
277 ele._encode(self, 0)?;
278 }
279 Ok(())
280 }
281 }
282}
283
284impl TarsEncodeListTrait<i8> for TarsEncoder {
285 fn write_list(&mut self, tag: u8, ele: &Vec<i8>) -> Result<(), EncodeErr> {
286 let len = ele.len();
287 if len > i32::max_value() as usize {
288 Err(EncodeErr::DataTooBigErr)
289 } else {
290 self.put_head(tag, EnSimplelist)?;
291 self.put_head(0, EnInt8)?;
292 self.write_int32(0, len as i32)?;
293 self.buf
294 .extend_from_slice(unsafe { mem::transmute(ele.as_slice()) });
295 Ok(())
296 }
297 }
298}
299
300impl TarsEncodeListTrait<bool> for TarsEncoder {
301 fn write_list(&mut self, tag: u8, ele: &Vec<bool>) -> Result<(), EncodeErr> {
302 let len = ele.len();
303 if len > i32::max_value() as usize {
304 Err(EncodeErr::DataTooBigErr)
305 } else {
306 self.put_head(tag, EnSimplelist)?;
307 self.put_head(0, EnInt8)?;
308 self.write_int32(0, len as i32)?;
309 self.buf
310 .extend_from_slice(unsafe { mem::transmute(ele.as_slice()) });
311 Ok(())
312 }
313 }
314}
315
316pub trait EncodeTars {
318 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr>;
319}
320
321impl EncodeTars for i8 {
322 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
323 encoder.write_int8(tag, *self)
324 }
325}
326
327impl EncodeTars for i16 {
328 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
329 encoder.write_int16(tag, *self)
330 }
331}
332
333impl EncodeTars for i32 {
334 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
335 encoder.write_int32(tag, *self)
336 }
337}
338
339impl EncodeTars for i64 {
340 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
341 encoder.write_int64(tag, *self)
342 }
343}
344
345impl EncodeTars for u8 {
346 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
347 encoder.write_uint8(tag, *self)
348 }
349}
350
351impl EncodeTars for u16 {
352 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
353 encoder.write_uint16(tag, *self)
354 }
355}
356
357impl EncodeTars for u32 {
358 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
359 encoder.write_uint32(tag, *self)
360 }
361}
362
363impl EncodeTars for f32 {
364 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
365 encoder.write_float(tag, *self)
366 }
367}
368
369impl EncodeTars for f64 {
370 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
371 encoder.write_double(tag, *self)
372 }
373}
374
375impl EncodeTars for bool {
376 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
377 encoder.write_boolean(tag, *self)
378 }
379}
380
381impl EncodeTars for String {
382 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
383 encoder.write_string(tag, self)
384 }
385}
386
387impl<K, V> EncodeTars for BTreeMap<K, V>
388where
389 K: EncodeTars + Ord,
390 V: EncodeTars,
391{
392 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
393 encoder.write_map(tag, self)
394 }
395}
396
397impl<T> EncodeTars for Vec<T>
398where
399 T: EncodeTars,
400{
401 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
402 encoder.write_list(tag, self)
403 }
404}
405
406impl EncodeTars for Bytes {
407 fn _encode(&self, encoder: &mut TarsEncoder, tag: u8) -> Result<(), EncodeErr> {
408 encoder.write_bytes(tag, self)
409 }
410}
411
412#[cfg(test)]
413mod tests {
414 use super::*;
415
416 #[test]
417 fn test_encode_i8() {
418 let mut encoder = TarsEncoder::new();
419 let i0: i8 = -127;
420 let i3: i8 = 0;
421 let i1: i8 = 127;
422 let i2: i8 = -1;
423
424 encoder.write_int8(0, i0).unwrap();
425 encoder.write_int8(14, i1).unwrap();
426 encoder.write_int8(255, i2).unwrap();
427 encoder.write_int8(3, i3).unwrap();
428
429 assert_eq!(
430 &encoder.to_bytes(),
431 &b"\x00\x81\xe0\x7f\xf0\xff\xff\x3c"[..]
432 );
433 }
434
435 #[test]
436 fn test_encode_i16() {
437 let mut encoder = TarsEncoder::new();
438 let i0: i16 = -32768;
439 let i1: i16 = -127;
440 let i2: i16 = 32767;
441
442 encoder.write_int16(0, i0).unwrap();
443 encoder.write_int16(15, i1).unwrap();
444 encoder.write_int16(19, i2).unwrap();
445
446 assert_eq!(
447 &encoder.to_bytes(),
448 &b"\x01\x80\x00\xf0\x0f\x81\xf1\x13\x7f\xff"[..]
449 );
450 }
451
452 #[test]
453 fn test_encode_i32() {
454 let mut encoder = TarsEncoder::new();
455
456 let i0: i32 = 90909;
457 let i1: i32 = 255;
458 let i2: i32 = -127;
459 let i3: i32 = -95234;
460
461 encoder.write_int32(0, i0).unwrap();
462 encoder.write_int32(15, i1).unwrap();
463 encoder.write_int32(14, i2).unwrap();
464 encoder.write_int32(14, i3).unwrap();
465
466 assert_eq!(
467 &encoder.to_bytes(),
468 &b"\x02\x00\x01\x63\x1d\xf1\x0f\x00\xff\xe0\x81\xe2\xff\xfe\x8b\xfe"[..]
469 );
470 }
471
472 #[test]
473 fn test_encode_i64() {
474 let mut encoder = TarsEncoder::new();
475
476 let i0: i64 = -1;
477 let i1: i64 = -129;
478 let i2: i64 = -32769;
479 let i3: i64 = -2147483649;
480
481 encoder.write_int64(0, i0).unwrap();
482 encoder.write_int64(0, i1).unwrap();
483 encoder.write_int64(0, i2).unwrap();
484 encoder.write_int64(0, i3).unwrap();
485
486 assert_eq!(
487 &encoder.to_bytes(),
488 &b"\x00\xff\x01\xff\x7f\x02\xff\xff\x7f\xff\x03\xff\xff\xff\xff\x7f\xff\xff\xff"[..]
489 );
490 }
491
492 #[test]
493 fn test_encode_u8() {
494 let mut encoder = TarsEncoder::new();
495 let u0: u8 = 127;
496 let u1: u8 = 255;
497 let u2: u8 = 0;
498
499 encoder.write_uint8(0, u0).unwrap();
500 encoder.write_uint8(14, u1).unwrap();
501 encoder.write_uint8(255, u2).unwrap();
502
503 assert_eq!(&encoder.to_bytes(), &b"\x00\x7f\xe1\x00\xff\xfc\xff"[..]);
504 }
505
506 #[test]
507 fn test_encode_u16() {
508 let mut encoder = TarsEncoder::new();
509
510 let i0: u16 = 32768;
511 let i1: u16 = 255;
512 let i2: u16 = 65535;
513
514 encoder.write_uint16(0, i0).unwrap();
515 encoder.write_uint16(15, i1).unwrap();
516
517 encoder.write_uint16(19, i2).unwrap();
518 assert_eq!(
519 &encoder.to_bytes(),
520 &b"\x02\x00\x00\x80\x00\xf1\x0f\x00\xff\xf2\x13\x00\x00\xff\xff"[..]
521 );
522 }
523
524 #[test]
525 fn test_encode_u32() {
526 let mut encoder = TarsEncoder::new();
527 let u0: u32 = 88888;
528 let u1: u32 = 254;
529 let u2: u32 = 256;
530
531 encoder.write_uint32(0, u0).unwrap();
532 encoder.write_uint32(14, u1).unwrap();
533 encoder.write_uint32(14, u2).unwrap();
534
535 assert_eq!(
536 &encoder.to_bytes(),
537 &b"\x02\x00\x01\x5b\x38\xe1\x00\xfe\xe1\x01\x00"[..]
538 );
539 }
540
541 #[test]
542 fn test_encode_f32() {
543 let mut encoder = TarsEncoder::new();
544 let f1: f32 = 0.1472;
545 encoder.write_float(0, f1).unwrap();
546 assert_eq!(&encoder.to_bytes(), &b"\x04\x3e\x16\xbb\x99"[..]);
547 }
548
549 #[test]
550 fn test_encode_f64() {
551 let mut encoder = TarsEncoder::new();
552 let f1: f64 = 0.14723333;
553 encoder.write_double(0, f1).unwrap();
554 assert_eq!(
555 &encoder.to_bytes(),
556 &b"\x05\x3f\xc2\xd8\x8a\xb0\x9d\x97\x2a"[..]
557 );
558 }
559
560 #[test]
561 fn test_encode_bool() {
562 let mut encoder = TarsEncoder::new();
563 encoder.write_boolean(0, false).unwrap();
564 encoder.write_boolean(1, true).unwrap();
565 assert_eq!(&encoder.to_bytes(), &b"\x0c\x10\x01"[..]);
566 }
567
568 #[test]
569 fn test_encode_string() {
570 let mut encoder = TarsEncoder::new();
571 let s: String = "hello wrold!".to_string();
572 let expect_buf = "\x06\x0c".to_string() + &s;
573 encoder.write_string(0, &s).unwrap();
574 assert_eq!(&encoder.to_bytes(), &expect_buf);
575
576 let mut encoder = TarsEncoder::new();
577 let mut s1: String = String::new();
578 for _ in 0..0xf7f7f {
579 s1.push('z');
580 }
581 let expect_buf = "\x07\x00\x0f\x7f\x7f".to_string() + &s1;
582 encoder.write_string(0, &s1).unwrap();
583 assert_eq!(&encoder.to_bytes(), &expect_buf);
584 }
585
586 #[test]
587 fn test_encode_vec() {
588 let mut v2: Vec<i8> = Vec::with_capacity(0xf7f7f);
589 for _ in 0..0xf7f7f {
590 v2.push(-127);
591 }
592 let mut encoder = TarsEncoder::new();
593 encoder.write_list(0, &v2).unwrap();
594 let mut header_v: Vec<u8> = Vec::from(&b"\x0d\x00\x02\x00\x0f\x7f\x7f"[..]);
595 header_v.extend_from_slice(unsafe { mem::transmute(v2.as_slice()) });
596 assert_eq!(&encoder.to_bytes(), &header_v);
597
598 let mut v3: Vec<bool> = Vec::with_capacity(0xf6f7f);
599 let mut b = false;
600 for _ in 0..0xf6f7f {
601 v3.push(b);
602 b = !b;
603 }
604
605 let mut encoder = TarsEncoder::new();
606 encoder.write_list(0, &v3).unwrap();
607 let mut header_v: Vec<u8> = Vec::from(&b"\x0d\x00\x02\x00\x0f\x6f\x7f"[..]);
608 header_v.extend_from_slice(unsafe { mem::transmute(v3.as_slice()) });
609 assert_eq!(&encoder.to_bytes(), &header_v);
610
611 let mut v4: Vec<String> = Vec::with_capacity(0xf6f7e);
612 let str4 = "hello".repeat(128);
613 let str1 = "hello".to_string();
614 let times = 0xf6f7e / 2;
615 for _ in 0..times {
616 v4.push(str4.clone());
617 }
618 for _ in 0..times {
619 v4.push(str1.clone());
620 }
621
622 let mut encoder = TarsEncoder::new();
623 encoder.write_list(10, &v4).unwrap();
624 let buf = encoder.to_bytes();
625 assert_eq!(&buf[0..2], &b"\xa9\x02"[..]);
626 let len_in_u8: [u8; 4] = [buf[2], buf[3], buf[4], buf[5]];
627 let len: i32 = i32::from_be(unsafe { mem::transmute(len_in_u8) });
628 assert_eq!(len, v4.len() as i32);
629 }
630
631 #[test]
632 fn test_encode_map() {
633 let mut map: BTreeMap<String, i32> = BTreeMap::new();
634 map.insert("hello".to_string(), 32);
635 map.insert("world".to_string(), 42);
636
637 let mut encoder = TarsEncoder::new();
638 encoder.write_map(0, &map).unwrap();
639 assert_eq!(
640 &encoder.to_bytes(),
641 &b"\x08\x00\x02\x06\x05hello\x10\x20\x06\x05world\x10\x2a"[..]
642 );
643 }
644
645 #[test]
646 fn test_encode_bytes() {
647 let b = Bytes::from(&b"hello world!"[..]);
648 let mut encoder = TarsEncoder::new();
649 encoder.write_bytes(9, &b).unwrap();
650 assert_eq!(&encoder.to_bytes(), &b"\x9d\x00\x00\x0chello world!"[..]);
651 }
652}