1use crate::*;
2
3use std::{convert::TryFrom, str::FromStr};
4use std::collections::HashMap;
5
6mod stream_pos_retreve_helper {
9 enum OutputTarget<'a> {
10 Write(&'a mut dyn std::io::Write, Vec<u8>),
11 Vec(&'a mut Vec<u8>),
12 Bytes,
13 }
14 pub struct CodedOutputStream<'a> {
16 target: OutputTarget<'a>,
17 buffer: &'a mut [u8],
19 pub position: usize,
21 }
22}
23
24pub struct ProtobufMessageCodecHelper {}
25
26impl ProtobufMessageCodecHelper {
27 pub fn raw_measure(
28 value: impl ::protobuf::Message,
29 _purpose: &Option<RawEncodePurpose>,
30 ) -> CodecResult<usize> {
31 let size = value.compute_size() as usize;
32
33 Ok(size)
34 }
35
36 pub fn raw_encode<'a>(
37 value: impl ::protobuf::Message,
38 buf: &'a mut [u8],
39 _purpose: &Option<RawEncodePurpose>,
40 ) -> CodecResult<&'a mut [u8]> {
41 let size = value.compute_size() as usize;
42 let mut stream = ::protobuf::CodedOutputStream::bytes(buf);
43 value.write_to(&mut stream).map_err(|e| {
44 let msg = format!("encode protobuf::Message to stream error! {}", e);
45 error!("{}", msg);
46
47 CodecError::new(CodecErrorCode::OutOfLimit, msg)
48 })?;
49
50 Ok(&mut buf[size..])
54 }
55
56 pub fn raw_decode<'de, T>(buf: &'de [u8]) -> CodecResult<(T, &'de [u8])>
58 where
59 T: ::protobuf::Message,
60 {
61 let size = buf.len();
63
64 let mut stream = ::protobuf::CodedInputStream::from_bytes(buf);
66 let value = T::parse_from(&mut stream).map_err(|e| {
67 let msg = format!("decode protobuf::Message from stream error! {}", e);
68 error!("{}", msg);
69
70 CodecError::new(CodecErrorCode::InvalidFormat, msg)
71 })?;
72
73 assert_eq!(stream.pos() as usize, size);
74
75 Ok((value, &buf[size..]))
76 }
77}
78
79pub struct ProtobufCodecHelper {}
80
81impl ProtobufCodecHelper {
82 pub fn raw_measure<'a, T, P>(
83 value: &'a T,
84 purpose: &Option<RawEncodePurpose>,
85 ) -> CodecResult<usize>
86 where
87 P: TryFrom<&'a T>,
88 P: ::protobuf::Message,
89 <P as TryFrom<&'a T>>::Error: std::fmt::Display,
90 {
91 let value: P = P::try_from(value).map_err(|e: <P as TryFrom<&'a T>>::Error| {
92 let msg = format!("convert protobuf origin to protobuf::Message error! {}", e);
93 error!("{}", msg);
94
95 CodecError::new(CodecErrorCode::InvalidFormat, msg)
96 })?;
97
98 ProtobufMessageCodecHelper::raw_measure(value, purpose)
99 }
100
101 pub fn raw_encode<'a, 'b, T, P>(
102 value: &'b T,
103 buf: &'a mut [u8],
104 purpose: &Option<RawEncodePurpose>,
105 ) -> CodecResult<&'a mut [u8]>
106 where
107 P: TryFrom<&'b T>,
108 P: ::protobuf::Message,
109 <P as TryFrom<&'b T>>::Error: std::fmt::Display,
110 {
111 let value: P = P::try_from(value).map_err(|e: <P as TryFrom<&'b T>>::Error| {
112 let msg = format!("convert protobuf origin to protobuf::Message error! {}", e);
113 error!("{}", msg);
114
115 CodecError::new(CodecErrorCode::InvalidFormat, msg)
116 })?;
117
118 ProtobufMessageCodecHelper::raw_encode(value, buf, purpose)
119 }
120
121 pub fn raw_decode<'de, T, P>(buf: &'de [u8]) -> CodecResult<(T, &'de [u8])>
122 where
123 T: TryFrom<P>,
124 P: ::protobuf::Message,
125 <T as TryFrom<P>>::Error: std::fmt::Display,
126 {
127 let (msg, buf) = ProtobufMessageCodecHelper::raw_decode::<P>(buf)?;
128 let value: T = T::try_from(msg).map_err(|e: <T as TryFrom<P>>::Error| {
129 let msg = format!("convert protobuf message to type error! {}", e);
130 error!("{}", msg);
131
132 CodecError::new(CodecErrorCode::InvalidFormat, msg)
133 })?;
134
135 Ok((value, buf))
136 }
137
138 pub fn decode_buf<T>(buf: Vec<u8>) -> CodecResult<T>
139 where
140 T: for<'de> RawDecode<'de>,
141 {
142 let (item, _) = T::raw_decode(&buf)?;
143
144 Ok(item)
145 }
146
147 pub fn decode_string_list<T>(list: Vec<String>) -> CodecResult<Vec<T>>
148 where
149 T: FromStr,
150 <T as FromStr>::Err: std::fmt::Display,
151 CodecError: From<<T as FromStr>::Err>,
152 {
153 let mut result = Vec::with_capacity(list.len());
154 for s in list {
155 let item = T::from_str(&s)?;
156
157 result.push(item);
158 }
159
160 Ok(result)
161 }
162
163 pub fn encode_string_list<T>(list: &[T]) -> CodecResult<::protobuf::RepeatedField<String>>
164 where
165 T: ToString,
166 {
167 let mut result = Vec::with_capacity(list.len());
168 for item in list.iter() {
169 let buf = item.to_string();
170
171 result.push(buf);
172 }
173
174 Ok(result.into())
175 }
176
177 pub fn decode_buf_list<T>(list: impl Into<Vec<Vec<u8>>>) -> CodecResult<Vec<T>>
178 where
179 T: for<'de> RawDecode<'de>,
180 {
181 let list: Vec<Vec<u8>> = list.into();
182 let mut result = Vec::with_capacity(list.len());
183 for buf in list {
184 let (item, _) = T::raw_decode(&buf)?;
185
186 result.push(item);
187 }
188
189 Ok(result)
190 }
191
192 pub fn encode_buf_list<T>(list: &[T]) -> CodecResult<::protobuf::RepeatedField<Vec<u8>>>
193 where
194 T: RawEncode,
195 {
196 let mut result = Vec::with_capacity(list.len());
197 for item in list.iter() {
198 let buf = item.to_vec()?;
199
200 result.push(buf);
201 }
202
203 Ok(result.into())
204 }
205
206 pub fn decode_nested_item<T, P>(item: P) -> CodecResult<T>
208 where
209 T: TryFrom<P>,
210 <T as TryFrom<P>>::Error: std::fmt::Display,
211 CodecError: From<<T as TryFrom<P>>::Error>,
212 {
213 let ret = T::try_from(item)?;
214
215 Ok(ret)
216 }
217
218 pub fn encode_nested_item<'a, T, P>(item: &'a T) -> CodecResult<P>
220 where
221 P: TryFrom<&'a T>,
222 <P as TryFrom<&'a T>>::Error: std::fmt::Display,
223 CodecError: From<<P as TryFrom<&'a T>>::Error>,
224 {
225 let ret = P::try_from(item)?;
226
227 Ok(ret)
228 }
229
230 pub fn decode_nested_list<T, P>(list: impl Into<Vec<P>>) -> CodecResult<Vec<T>>
232 where
233 T: TryFrom<P>,
234 <T as TryFrom<P>>::Error: std::fmt::Display,
235 CodecError: From<<T as TryFrom<P>>::Error>,
236 {
237 let list: Vec<P> = list.into();
238 let mut result = Vec::with_capacity(list.len());
239 for v in list {
240 let item = T::try_from(v)?;
241
242 result.push(item);
243 }
244
245 Ok(result)
246 }
247
248 pub fn encode_nested_list<'a, T, P>(
249 list: &'a Vec<T>,
250 ) -> CodecResult<::protobuf::RepeatedField<P>>
251 where
252 T: 'a,
253 P: TryFrom<&'a T>,
254 <P as TryFrom<&'a T>>::Error: std::fmt::Display,
255 CodecError: From<<P as TryFrom<&'a T>>::Error>,
256 {
257 let mut result = Vec::with_capacity(list.len());
258 for v in list {
259 let item = P::try_from(v)?;
260
261 result.push(item);
262 }
263
264 Ok(result.into())
265 }
266
267 pub fn decode_value<T, P>(value: P) -> CodecResult<T>
268 where
269 T: TryFrom<P>,
270 <T as TryFrom<P>>::Error: std::fmt::Display,
271 {
272 T::try_from(value).map_err(|e| {
273 let msg = format!(
274 "decode value to target type failed! {} => {}, {}",
275 std::any::type_name::<P>(),
276 std::any::type_name::<T>(),
277 e
278 );
279
280 error!("{}", msg);
281 CodecError::new(CodecErrorCode::InvalidFormat, msg)
282 })
283 }
284
285 pub fn decode_value_list<T, P>(list: impl Into<Vec<P>>) -> CodecResult<Vec<T>>
286 where
287 T: TryFrom<P>,
288 <T as TryFrom<P>>::Error: std::fmt::Display,
289 {
290 let list = list.into();
291 let mut result = Vec::with_capacity(list.len());
292 for v in list {
293 let item = Self::decode_value(v)?;
294
295 result.push(item);
296 }
297
298 Ok(result)
299 }
300
301 pub fn decode_str_value<T>(value: &str) -> CodecResult<T>
302 where
303 T: FromStr,
304 <T as FromStr>::Err: std::fmt::Display,
305 {
306 T::from_str(value).map_err(|e| {
307 let msg = format!(
308 "decode string to target type failed! {} => {}, {}",
309 value,
310 std::any::type_name::<T>(),
311 e
312 );
313
314 error!("{}", msg);
315 CodecError::new(CodecErrorCode::InvalidFormat, msg)
316 })
317 }
318}
319
320pub trait ProtobufEncode {}
321pub trait ProtobufDecode {}
322
323pub trait ProtobufTransform<T>: Sized {
324 fn transform(value: T) -> CodecResult<Self>;
325}
326
327impl <T, U: ProtobufTransform<T>> ProtobufTransform<Vec<T>> for Vec<U> {
328 fn transform(value: Vec<T>) -> CodecResult<Self> {
329 let mut list = Vec::new();
330 for item in value.into_iter() {
331 list.push(ProtobufTransform::transform(item)?);
332 }
333 Ok(list)
334 }
335}
336
337impl <'a, T: 'a, U: ProtobufTransform<&'a T>> ProtobufTransform<&'a Vec<T>> for Vec<U> {
338 fn transform(value: &'a Vec<T>) -> CodecResult<Self> {
339 let mut list = Vec::new();
340 for item in value.into_iter() {
341 list.push(ProtobufTransform::transform(item)?);
342 }
343 Ok(list)
344 }
345}
346
347impl <K, T, Y: ProtobufTransform<K> + std::cmp::Eq + std::hash::Hash, U: ProtobufTransform<T>> ProtobufTransform<HashMap<K, T>> for HashMap<Y, U> {
348 fn transform(value: HashMap<K, T>) -> CodecResult<Self> {
349 let mut list = HashMap::new();
350 for (k, t) in value.into_iter() {
351 list.insert(ProtobufTransform::transform(k)?, ProtobufTransform::transform(t)?);
352 }
353 Ok(list)
354 }
355}
356
357impl <'a, K: 'a, T: 'a, Y: ProtobufTransform<&'a K> + std::cmp::Eq + std::hash::Hash, U: ProtobufTransform<&'a T>> ProtobufTransform<&'a HashMap<K, T>> for HashMap<Y, U> {
358 fn transform(value: &'a HashMap<K, T>) -> CodecResult<Self> {
359 let mut list = HashMap::new();
360 for (k, t) in value.into_iter() {
361 list.insert(ProtobufTransform::transform(k)?, ProtobufTransform::transform(t)?);
362 }
363 Ok(list)
364 }
365}
366
367impl<T, U: ProtobufTransform<T>> ProtobufTransform<Option<T>> for Option<U> {
368 fn transform(value: Option<T>) -> CodecResult<Self> {
369 match value {
370 Some(value) => Ok(Some(ProtobufTransform::transform(value)?)),
371 None => Ok(None)
372 }
373 }
374}
375
376impl<'a, T: 'a, U: ProtobufTransform<&'a T>> ProtobufTransform<&'a Option<T>> for Option<U> {
377 fn transform(value: &'a Option<T>) -> CodecResult<Self> {
378 match value {
379 Some(value) => Ok(Some(ProtobufTransform::transform(value)?)),
380 None => Ok(None)
381 }
382 }
383}
384
385impl ProtobufTransform<i32> for i8 {
386 fn transform(value: i32) -> CodecResult<Self> {
387 Ok(value as i8)
388 }
389}
390
391impl ProtobufTransform<i32> for u8 {
392 fn transform(value: i32) -> CodecResult<Self> {
393 Ok(value as u8)
394 }
395}
396
397impl ProtobufTransform<u32> for u8 {
398 fn transform(value: u32) -> CodecResult<Self> {
399 Ok(value as u8)
400 }
401}
402
403impl ProtobufTransform<i32> for i16 {
404 fn transform(value: i32) -> CodecResult<Self> {
405 Ok(value as i16)
406 }
407}
408
409impl ProtobufTransform<i32> for u16 {
410 fn transform(value: i32) -> CodecResult<Self> {
411 Ok(value as u16)
412 }
413}
414
415impl ProtobufTransform<u32> for u16 {
416 fn transform(value: u32) -> CodecResult<Self> {
417 Ok(value as u16)
418 }
419}
420
421impl ProtobufTransform<&i32> for i16 {
422 fn transform(value: &i32) -> CodecResult<Self> {
423 Ok(*value as i16)
424 }
425}
426
427impl ProtobufTransform<&u32> for u16 {
428 fn transform(value: &u32) -> CodecResult<Self> {
429 Ok(*value as u16)
430 }
431}
432
433impl ProtobufTransform<i32> for i32 {
434 fn transform(value: i32) -> CodecResult<Self> {
435 Ok(value)
436 }
437}
438
439impl ProtobufTransform<i8> for i32 {
440 fn transform(value: i8) -> CodecResult<Self> {
441 Ok(value as i32)
442 }
443}
444
445impl ProtobufTransform<u8> for i32 {
446 fn transform(value: u8) -> CodecResult<Self> {
447 Ok(value as i32)
448 }
449}
450
451impl ProtobufTransform<i16> for i32 {
452 fn transform(value: i16) -> CodecResult<Self> {
453 Ok(value as i32)
454 }
455}
456
457impl ProtobufTransform<u16> for i32 {
458 fn transform(value: u16) -> CodecResult<Self> {
459 Ok(value as i32)
460 }
461}
462
463impl ProtobufTransform<&i8> for i32 {
464 fn transform(value: &i8) -> CodecResult<Self> {
465 Ok(*value as i32)
466 }
467}
468
469impl ProtobufTransform<&i16> for i32 {
470 fn transform(value: &i16) -> CodecResult<Self> {
471 Ok(*value as i32)
472 }
473}
474
475impl ProtobufTransform<&u8> for i32 {
476 fn transform(value: &u8) -> CodecResult<Self> {
477 Ok(*value as i32)
478 }
479}
480
481impl ProtobufTransform<&u16> for i32 {
482 fn transform(value: &u16) -> CodecResult<Self> {
483 Ok(*value as i32)
484 }
485}
486
487impl ProtobufTransform<u32> for u32 {
488 fn transform(value: u32) -> CodecResult<Self> {
489 Ok(value)
490 }
491}
492
493impl ProtobufTransform<u8> for u32 {
494 fn transform(value: u8) -> CodecResult<Self> {
495 Ok(value as u32)
496 }
497}
498
499impl ProtobufTransform<u16> for u32 {
500 fn transform(value: u16) -> CodecResult<Self> {
501 Ok(value as u32)
502 }
503}
504
505impl ProtobufTransform<&u8> for u32 {
506 fn transform(value: &u8) -> CodecResult<Self> {
507 Ok(*value as u32)
508 }
509}
510
511impl ProtobufTransform<&u16> for u32 {
512 fn transform(value: &u16) -> CodecResult<Self> {
513 Ok(*value as u32)
514 }
515}
516
517impl ProtobufTransform<&i32> for i32 {
518 fn transform(value: &i32) -> CodecResult<Self> {
519 Ok(*value)
520 }
521}
522
523impl ProtobufTransform<&u32> for u32 {
524 fn transform(value: &u32) -> CodecResult<Self> {
525 Ok(*value)
526 }
527}
528
529impl ProtobufTransform<i64> for i64 {
530 fn transform(value: i64) -> CodecResult<Self> {
531 Ok(value)
532 }
533}
534
535impl ProtobufTransform<u64> for u64 {
536 fn transform(value: u64) -> CodecResult<Self> {
537 Ok(value)
538 }
539}
540
541impl ProtobufTransform<&i64> for i64 {
542 fn transform(value: &i64) -> CodecResult<Self> {
543 Ok(*value)
544 }
545}
546
547impl ProtobufTransform<&u64> for u64 {
548 fn transform(value: &u64) -> CodecResult<Self> {
549 Ok(*value)
550 }
551}
552
553impl ProtobufTransform<f32> for f32 {
554 fn transform(value: f32) -> CodecResult<Self> {
555 Ok(value)
556 }
557}
558
559impl ProtobufTransform<&f32> for f32 {
560 fn transform(value: &f32) -> CodecResult<Self> {
561 Ok(*value)
562 }
563}
564
565impl ProtobufTransform<f64> for f64 {
566 fn transform(value: f64) -> CodecResult<Self> {
567 Ok(value)
568 }
569}
570
571impl ProtobufTransform<&f64> for f64 {
572 fn transform(value: &f64) -> CodecResult<Self> {
573 Ok(*value)
574 }
575}
576
577impl ProtobufTransform<String> for String {
578 fn transform(value: String) -> CodecResult<Self> {
579 Ok(value)
580 }
581}
582
583impl ProtobufTransform<&String> for String {
584 fn transform(value: &String) -> CodecResult<Self> {
585 Ok(value.to_string())
586 }
587}
588
589impl ProtobufTransform<bool> for bool {
590 fn transform(value: bool) -> CodecResult<Self> {
591 Ok(value)
592 }
593}
594
595impl ProtobufTransform<&bool> for bool {
596 fn transform(value: &bool) -> CodecResult<Self> {
597 Ok(*value)
598 }
599}
600
601impl ProtobufTransform<u8> for u8 {
602 fn transform(value: u8) -> CodecResult<Self> {
603 Ok(value)
604 }
605}
606
607impl ProtobufTransform<&u8> for u8 {
608 fn transform(value: &u8) -> CodecResult<Self> {
609 Ok(*value)
610 }
611}
612
613impl ProtobufTransform<u16> for u16 {
614 fn transform(value: u16) -> CodecResult<Self> {
615 Ok(value)
616 }
617}
618
619impl ProtobufTransform<&u16> for u16 {
620 fn transform(value: &u16) -> CodecResult<Self> {
621 Ok(*value)
622 }
623}
624
625#[macro_export]
626macro_rules! impl_default_protobuf_raw_codec {
627 ($name:ty, $proto_name:ty) => {
628 impl bucky_raw_codec::RawEncode for $name {
629 fn raw_measure(
630 &self,
631 purpose: &Option<bucky_raw_codec::RawEncodePurpose>,
632 ) -> bucky_raw_codec::CodecResult<usize> {
633 bucky_raw_codec::ProtobufCodecHelper::raw_measure::<$name, $proto_name>(&self, purpose)
635 }
636 fn raw_encode<'a>(
637 &self,
638 buf: &'a mut [u8],
639 purpose: &Option<bucky_raw_codec::RawEncodePurpose>,
640 ) -> bucky_raw_codec::CodecResult<&'a mut [u8]> {
641 bucky_raw_codec::ProtobufCodecHelper::raw_encode::<$name, $proto_name>(self, buf, purpose)
643 }
644 }
645 impl<'de> bucky_raw_codec::RawDecode<'de> for $name {
646 fn raw_decode(buf: &'de [u8]) -> bucky_raw_codec::CodecResult<(Self, &'de [u8])> {
647 bucky_raw_codec::ProtobufCodecHelper::raw_decode::<$name, $proto_name>(buf)
649 }
650 }
651 };
652
653 ($name:ident) => {
654 bucky_raw_codec::impl_default_protobuf_raw_codec!($name, protos::$name);
655 };
656}
657
658#[macro_export]
660macro_rules! inner_impl_default_protobuf_raw_codec {
661 ($name:ty, $proto_name:ty) => {
662 impl crate::RawEncode for $name {
663 fn raw_measure(
664 &self,
665 purpose: &Option<crate::RawEncodePurpose>,
666 ) -> crate::CodecResult<usize> {
667 crate::ProtobufCodecHelper::raw_measure::<$name, $proto_name>(&self, purpose)
669 }
670 fn raw_encode<'a>(
671 &self,
672 buf: &'a mut [u8],
673 purpose: &Option<crate::RawEncodePurpose>,
674 ) -> crate::CodecResult<&'a mut [u8]> {
675 crate::ProtobufCodecHelper::raw_encode::<$name, $proto_name>(self, buf, purpose)
677 }
678 }
679 impl<'de> crate::RawDecode<'de> for $name {
680 fn raw_decode(buf: &'de [u8]) -> crate::CodecResult<(Self, &'de [u8])> {
681 crate::ProtobufCodecHelper::raw_decode::<$name, $proto_name>(buf)
683 }
684 }
685 };
686
687 ($name:ident) => {
688 crate::inner_impl_default_protobuf_raw_codec!($name, protos::$name);
689 };
690}
691
692#[macro_export]
694macro_rules! mod_impl_empty_protobuf_raw_codec {
695 ($m:ident, $name:ty, $proto_name:ty) => {
696 impl $m::RawEncode for $name {
697 fn raw_measure(
698 &self,
699 _purpose: &Option<$m::RawEncodePurpose>,
700 ) -> $m::CodecResult<usize> {
701 Ok(0)
702 }
703 fn raw_encode<'a>(
704 &self,
705 buf: &'a mut [u8],
706 _purpose: &Option<$m::RawEncodePurpose>,
707 ) -> $m::CodecResult<&'a mut [u8]> {
708 (Ok(buf))
709 }
710 }
711 impl<'de> $m::RawDecode<'de> for $name {
712 fn raw_decode(buf: &'de [u8]) -> $m::CodecResult<(Self, &'de [u8])> {
713 let (msg, buf) = $m::ProtobufMessageCodecHelper::raw_decode::<$proto_name>(buf)?;
716
717 use ::protobuf::Message;
719 if let Some(list) = &msg.get_unknown_fields().fields {
720 warn!("got unknown fields! count={}", list.len());
721 }
722 Ok((Self {}, buf))
723 }
724 }
725 };
726
727 ($m:ident, $name:ident) => {
728 $m::mod_impl_empty_protobuf_raw_codec!($m, $name, $m::EmptyContent);
729 };
730}
731
732#[macro_export]
733macro_rules! impl_empty_protobuf_raw_codec {
734 ($name:ty, $proto_name:ty) => {
735 mod_impl_empty_protobuf_raw_codec!(bucky_raw_codec, $name, $proto_name);
736 };
737
738 ($name:ident) => {
739 mod_impl_empty_protobuf_raw_codec!(bucky_raw_codec, $name);
740 };
741}
742
743#[macro_export]
744macro_rules! inner_impl_empty_protobuf_raw_codec {
745 ($name:ty, $proto_name:ty) => {
746 crate::mod_impl_empty_protobuf_raw_codec!(crate, $name, $proto_name);
747 };
748
749 ($name:ident) => {
750 crate::mod_impl_empty_protobuf_raw_codec!(crate, $name);
751 };
752}
753
754#[cfg(test)]
755mod test {
756 use crate::*;
757 use crate as bucky_raw_codec;
758 use ::protobuf::Message;
759 use std::convert::TryFrom;
760
761 #[derive(Clone, Debug, RawEncode, RawDecode)]
763 struct EmptyContent {}
764
765 struct EmptyContent2 {}
766
767 inner_impl_empty_protobuf_raw_codec!(EmptyContent2);
768
769 struct EmptyContentV1 {
770 name: Option<String>,
771 }
772
773 impl TryFrom<protos::EmptyContentV1> for EmptyContentV1 {
774 type Error = CodecError;
775 fn try_from(mut value: protos::EmptyContentV1) -> CodecResult<Self> {
776 let mut ret = Self { name: None };
777
778 if value.has_name() {
779 ret.name = Some(value.take_name());
780 }
781
782 Ok(ret)
783 }
784 }
785 impl TryFrom<&EmptyContentV1> for protos::EmptyContentV1 {
786 type Error = CodecError;
787 fn try_from(value: &EmptyContentV1) -> CodecResult<Self> {
788 let mut ret = Self::new();
789 if let Some(name) = &value.name {
790 ret.set_name(name.to_owned());
791 }
792
793 Ok(ret)
794 }
795 }
796 inner_impl_default_protobuf_raw_codec!(EmptyContentV1);
797
798 #[test]
799 fn test_protobuf() {
800 {
802 let content = protos::EmptyContent::new();
803 let size = content.compute_size();
804 assert_eq!(size, 0);
805
806 let buf = vec![0u8; 0];
807 let (content_v1, _) = EmptyContentV1::raw_decode(&buf).unwrap();
808 assert!(content_v1.name.is_none());
809 }
810
811 {
813 let content_v1 = EmptyContentV1 {
814 name: Some("xxx".to_owned()),
815 };
816 let buf = content_v1.to_vec().unwrap();
817 assert!(buf.len() > 0);
818
819 let (_content, left_buf) = EmptyContent::raw_decode(&buf).unwrap();
822 assert!(left_buf.len() == buf.len());
823
824 let (_content, left_buf) = EmptyContent2::raw_decode(&buf).unwrap();
826 assert!(left_buf.len() == 0);
827 }
828
829 let content2 = EmptyContent {};
830 let buf = content2.to_vec().unwrap();
831 assert_eq!(buf.len(), 0);
832 }
833
834 #[test]
835 fn test_helper() {
836 let mut source: u32 = u32::MAX;
837 let ret = ProtobufCodecHelper::decode_value::<u8, u32>(source);
838 assert!(ret.is_err());
839
840 source = u8::MAX as u32;
841 let ret = ProtobufCodecHelper::decode_value::<u8, u32>(source);
842 assert!(ret.is_ok());
843 assert_eq!(ret.unwrap(), u8::MAX);
844 }
845}