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 ) -> BuckyResult<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 ) -> BuckyResult<&'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 BuckyError::new(BuckyErrorCode::OutOfLimit, msg)
48 })?;
49
50 Ok(&mut buf[size..])
54 }
55
56 pub fn raw_decode<'de, T>(buf: &'de [u8]) -> BuckyResult<(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 BuckyError::new(BuckyErrorCode::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 ) -> BuckyResult<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 BuckyError::new(BuckyErrorCode::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 ) -> BuckyResult<&'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 BuckyError::new(BuckyErrorCode::InvalidFormat, msg)
116 })?;
117
118 ProtobufMessageCodecHelper::raw_encode(value, buf, purpose)
119 }
120
121 pub fn raw_decode<'de, T, P>(buf: &'de [u8]) -> BuckyResult<(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 BuckyError::new(BuckyErrorCode::InvalidFormat, msg)
133 })?;
134
135 Ok((value, buf))
136 }
137
138 pub fn decode_buf<T>(buf: Vec<u8>) -> BuckyResult<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>) -> BuckyResult<Vec<T>>
148 where
149 T: FromStr,
150 <T as FromStr>::Err: std::fmt::Display,
151 BuckyError: 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]) -> BuckyResult<::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>>>) -> BuckyResult<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]) -> BuckyResult<::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) -> BuckyResult<T>
208 where
209 T: TryFrom<P>,
210 <T as TryFrom<P>>::Error: std::fmt::Display,
211 BuckyError: 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) -> BuckyResult<P>
220 where
221 P: TryFrom<&'a T>,
222 <P as TryFrom<&'a T>>::Error: std::fmt::Display,
223 BuckyError: 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>>) -> BuckyResult<Vec<T>>
232 where
233 T: TryFrom<P>,
234 <T as TryFrom<P>>::Error: std::fmt::Display,
235 BuckyError: 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 ) -> BuckyResult<::protobuf::RepeatedField<P>>
251 where
252 T: 'a,
253 P: TryFrom<&'a T>,
254 <P as TryFrom<&'a T>>::Error: std::fmt::Display,
255 BuckyError: 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) -> BuckyResult<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 BuckyError::new(BuckyErrorCode::InvalidFormat, msg)
282 })
283 }
284
285 pub fn decode_value_list<T, P>(list: impl Into<Vec<P>>) -> BuckyResult<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) -> BuckyResult<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 BuckyError::new(BuckyErrorCode::InvalidFormat, msg)
316 })
317 }
318}
319
320pub trait ProtobufEncode {}
321pub trait ProtobufDecode {}
322
323pub trait ProtobufTransform<T>: Sized {
324 fn transform(value: T) -> BuckyResult<Self>;
325}
326impl <T, U: ProtobufTransform<T>> ProtobufTransform<Vec<T>> for Vec<U> {
340 fn transform(value: Vec<T>) -> BuckyResult<Self> {
341 let mut list = Vec::new();
342 for item in value.into_iter() {
343 list.push(ProtobufTransform::transform(item)?);
344 }
345 Ok(list)
346 }
347}
348
349impl <'a, T: 'a, U: ProtobufTransform<&'a T>> ProtobufTransform<&'a Vec<T>> for Vec<U> {
350 fn transform(value: &'a Vec<T>) -> BuckyResult<Self> {
351 let mut list = Vec::new();
352 for item in value.into_iter() {
353 list.push(ProtobufTransform::transform(item)?);
354 }
355 Ok(list)
356 }
357}
358
359impl <K, T, Y: ProtobufTransform<K> + std::cmp::Eq + std::hash::Hash, U: ProtobufTransform<T>> ProtobufTransform<HashMap<K, T>> for HashMap<Y, U> {
360 fn transform(value: HashMap<K, T>) -> BuckyResult<Self> {
361 let mut list = HashMap::new();
362 for (k, t) in value.into_iter() {
363 list.insert(ProtobufTransform::transform(k)?, ProtobufTransform::transform(t)?);
364 }
365 Ok(list)
366 }
367}
368
369impl <'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> {
370 fn transform(value: &'a HashMap<K, T>) -> BuckyResult<Self> {
371 let mut list = HashMap::new();
372 for (k, t) in value.into_iter() {
373 list.insert(ProtobufTransform::transform(k)?, ProtobufTransform::transform(t)?);
374 }
375 Ok(list)
376 }
377}
378
379impl<T, U: ProtobufTransform<T>> ProtobufTransform<Option<T>> for Option<U> {
395 fn transform(value: Option<T>) -> BuckyResult<Self> {
396 match value {
397 Some(value) => Ok(Some(ProtobufTransform::transform(value)?)),
398 None => Ok(None)
399 }
400 }
401}
402
403impl<'a, T: 'a, U: ProtobufTransform<&'a T>> ProtobufTransform<&'a Option<T>> for Option<U> {
404 fn transform(value: &'a Option<T>) -> BuckyResult<Self> {
405 match value {
406 Some(value) => Ok(Some(ProtobufTransform::transform(value)?)),
407 None => Ok(None)
408 }
409 }
410}
411
412impl ProtobufTransform<i32> for i8 {
413 fn transform(value: i32) -> BuckyResult<Self> {
414 Ok(value as i8)
415 }
416}
417
418impl ProtobufTransform<i32> for u8 {
419 fn transform(value: i32) -> BuckyResult<Self> {
420 Ok(value as u8)
421 }
422}
423
424impl ProtobufTransform<u32> for u8 {
425 fn transform(value: u32) -> BuckyResult<Self> {
426 Ok(value as u8)
427 }
428}
429
430impl ProtobufTransform<i32> for i16 {
431 fn transform(value: i32) -> BuckyResult<Self> {
432 Ok(value as i16)
433 }
434}
435
436impl ProtobufTransform<i32> for u16 {
437 fn transform(value: i32) -> BuckyResult<Self> {
438 Ok(value as u16)
439 }
440}
441
442impl ProtobufTransform<u32> for u16 {
443 fn transform(value: u32) -> BuckyResult<Self> {
444 Ok(value as u16)
445 }
446}
447
448impl ProtobufTransform<&i32> for i16 {
449 fn transform(value: &i32) -> BuckyResult<Self> {
450 Ok(*value as i16)
451 }
452}
453
454impl ProtobufTransform<&u32> for u16 {
455 fn transform(value: &u32) -> BuckyResult<Self> {
456 Ok(*value as u16)
457 }
458}
459
460impl ProtobufTransform<i32> for i32 {
461 fn transform(value: i32) -> BuckyResult<Self> {
462 Ok(value)
463 }
464}
465
466impl ProtobufTransform<i8> for i32 {
467 fn transform(value: i8) -> BuckyResult<Self> {
468 Ok(value as i32)
469 }
470}
471
472impl ProtobufTransform<u8> for i32 {
473 fn transform(value: u8) -> BuckyResult<Self> {
474 Ok(value as i32)
475 }
476}
477
478impl ProtobufTransform<i16> for i32 {
479 fn transform(value: i16) -> BuckyResult<Self> {
480 Ok(value as i32)
481 }
482}
483
484impl ProtobufTransform<u16> for i32 {
485 fn transform(value: u16) -> BuckyResult<Self> {
486 Ok(value as i32)
487 }
488}
489
490impl ProtobufTransform<&i8> for i32 {
491 fn transform(value: &i8) -> BuckyResult<Self> {
492 Ok(*value as i32)
493 }
494}
495
496impl ProtobufTransform<&i16> for i32 {
497 fn transform(value: &i16) -> BuckyResult<Self> {
498 Ok(*value as i32)
499 }
500}
501
502impl ProtobufTransform<&u8> for i32 {
503 fn transform(value: &u8) -> BuckyResult<Self> {
504 Ok(*value as i32)
505 }
506}
507
508impl ProtobufTransform<&u16> for i32 {
509 fn transform(value: &u16) -> BuckyResult<Self> {
510 Ok(*value as i32)
511 }
512}
513
514impl ProtobufTransform<u32> for u32 {
515 fn transform(value: u32) -> BuckyResult<Self> {
516 Ok(value)
517 }
518}
519
520impl ProtobufTransform<u8> for u32 {
521 fn transform(value: u8) -> BuckyResult<Self> {
522 Ok(value as u32)
523 }
524}
525
526impl ProtobufTransform<u16> for u32 {
527 fn transform(value: u16) -> BuckyResult<Self> {
528 Ok(value as u32)
529 }
530}
531
532impl ProtobufTransform<&u8> for u32 {
533 fn transform(value: &u8) -> BuckyResult<Self> {
534 Ok(*value as u32)
535 }
536}
537
538impl ProtobufTransform<&u16> for u32 {
539 fn transform(value: &u16) -> BuckyResult<Self> {
540 Ok(*value as u32)
541 }
542}
543
544impl ProtobufTransform<&i32> for i32 {
545 fn transform(value: &i32) -> BuckyResult<Self> {
546 Ok(*value)
547 }
548}
549
550impl ProtobufTransform<&u32> for u32 {
551 fn transform(value: &u32) -> BuckyResult<Self> {
552 Ok(*value)
553 }
554}
555
556impl ProtobufTransform<i64> for i64 {
557 fn transform(value: i64) -> BuckyResult<Self> {
558 Ok(value)
559 }
560}
561
562impl ProtobufTransform<u64> for u64 {
563 fn transform(value: u64) -> BuckyResult<Self> {
564 Ok(value)
565 }
566}
567
568impl ProtobufTransform<&i64> for i64 {
569 fn transform(value: &i64) -> BuckyResult<Self> {
570 Ok(*value)
571 }
572}
573
574impl ProtobufTransform<&u64> for u64 {
575 fn transform(value: &u64) -> BuckyResult<Self> {
576 Ok(*value)
577 }
578}
579
580impl ProtobufTransform<f32> for f32 {
581 fn transform(value: f32) -> BuckyResult<Self> {
582 Ok(value)
583 }
584}
585
586impl ProtobufTransform<&f32> for f32 {
587 fn transform(value: &f32) -> BuckyResult<Self> {
588 Ok(*value)
589 }
590}
591
592impl ProtobufTransform<f64> for f64 {
593 fn transform(value: f64) -> BuckyResult<Self> {
594 Ok(value)
595 }
596}
597
598impl ProtobufTransform<&f64> for f64 {
599 fn transform(value: &f64) -> BuckyResult<Self> {
600 Ok(*value)
601 }
602}
603
604impl ProtobufTransform<String> for String {
605 fn transform(value: String) -> BuckyResult<Self> {
606 Ok(value)
607 }
608}
609
610impl ProtobufTransform<&String> for String {
611 fn transform(value: &String) -> BuckyResult<Self> {
612 Ok(value.to_string())
613 }
614}
615
616impl ProtobufTransform<bool> for bool {
617 fn transform(value: bool) -> BuckyResult<Self> {
618 Ok(value)
619 }
620}
621
622impl ProtobufTransform<&bool> for bool {
623 fn transform(value: &bool) -> BuckyResult<Self> {
624 Ok(*value)
625 }
626}
627
628impl ProtobufTransform<u8> for u8 {
629 fn transform(value: u8) -> BuckyResult<Self> {
630 Ok(value)
631 }
632}
633
634impl ProtobufTransform<&u8> for u8 {
635 fn transform(value: &u8) -> BuckyResult<Self> {
636 Ok(*value)
637 }
638}
639
640impl ProtobufTransform<u16> for u16 {
641 fn transform(value: u16) -> BuckyResult<Self> {
642 Ok(value)
643 }
644}
645
646impl ProtobufTransform<&u16> for u16 {
647 fn transform(value: &u16) -> BuckyResult<Self> {
648 Ok(*value)
649 }
650}
651
652#[macro_export]
806macro_rules! impl_default_protobuf_raw_codec {
807 ($name:ty, $proto_name:ty) => {
808 impl cyfs_base::RawEncode for $name {
809 fn raw_measure(
810 &self,
811 purpose: &Option<cyfs_base::RawEncodePurpose>,
812 ) -> cyfs_base::BuckyResult<usize> {
813 cyfs_base::ProtobufCodecHelper::raw_measure::<$name, $proto_name>(&self, purpose)
815 }
816 fn raw_encode<'a>(
817 &self,
818 buf: &'a mut [u8],
819 purpose: &Option<cyfs_base::RawEncodePurpose>,
820 ) -> cyfs_base::BuckyResult<&'a mut [u8]> {
821 cyfs_base::ProtobufCodecHelper::raw_encode::<$name, $proto_name>(self, buf, purpose)
823 }
824 }
825 impl<'de> cyfs_base::RawDecode<'de> for $name {
826 fn raw_decode(buf: &'de [u8]) -> cyfs_base::BuckyResult<(Self, &'de [u8])> {
827 cyfs_base::ProtobufCodecHelper::raw_decode::<$name, $proto_name>(buf)
829 }
830 }
831 };
832
833 ($name:ident) => {
834 cyfs_base::impl_default_protobuf_raw_codec!($name, protos::$name);
835 };
836}
837
838#[macro_export]
840macro_rules! inner_impl_default_protobuf_raw_codec {
841 ($name:ty, $proto_name:ty) => {
842 impl crate::RawEncode for $name {
843 fn raw_measure(
844 &self,
845 purpose: &Option<crate::RawEncodePurpose>,
846 ) -> crate::BuckyResult<usize> {
847 crate::ProtobufCodecHelper::raw_measure::<$name, $proto_name>(&self, purpose)
849 }
850 fn raw_encode<'a>(
851 &self,
852 buf: &'a mut [u8],
853 purpose: &Option<crate::RawEncodePurpose>,
854 ) -> crate::BuckyResult<&'a mut [u8]> {
855 crate::ProtobufCodecHelper::raw_encode::<$name, $proto_name>(self, buf, purpose)
857 }
858 }
859 impl<'de> crate::RawDecode<'de> for $name {
860 fn raw_decode(buf: &'de [u8]) -> crate::BuckyResult<(Self, &'de [u8])> {
861 crate::ProtobufCodecHelper::raw_decode::<$name, $proto_name>(buf)
863 }
864 }
865 };
866
867 ($name:ident) => {
868 crate::inner_impl_default_protobuf_raw_codec!($name, protos::$name);
869 };
870}
871
872#[macro_export]
874macro_rules! mod_impl_empty_protobuf_raw_codec {
875 ($m:ident, $name:ty, $proto_name:ty) => {
876 impl $m::RawEncode for $name {
877 fn raw_measure(
878 &self,
879 _purpose: &Option<$m::RawEncodePurpose>,
880 ) -> $m::BuckyResult<usize> {
881 Ok(0)
882 }
883 fn raw_encode<'a>(
884 &self,
885 buf: &'a mut [u8],
886 _purpose: &Option<$m::RawEncodePurpose>,
887 ) -> $m::BuckyResult<&'a mut [u8]> {
888 (Ok(buf))
889 }
890 }
891 impl<'de> $m::RawDecode<'de> for $name {
892 fn raw_decode(buf: &'de [u8]) -> $m::BuckyResult<(Self, &'de [u8])> {
893 let (msg, buf) = $m::ProtobufMessageCodecHelper::raw_decode::<$proto_name>(buf)?;
896
897 use ::protobuf::Message;
899 if let Some(list) = &msg.get_unknown_fields().fields {
900 warn!("got unknown fields! count={}", list.len());
901 }
902 Ok((Self {}, buf))
903 }
904 }
905 };
906
907 ($m:ident, $name:ident) => {
908 $m::mod_impl_empty_protobuf_raw_codec!($m, $name, $m::EmptyContent);
909 };
910}
911
912#[macro_export]
913macro_rules! impl_empty_protobuf_raw_codec {
914 ($name:ty, $proto_name:ty) => {
915 mod_impl_empty_protobuf_raw_codec!(cyfs_base, $name, $proto_name);
916 };
917
918 ($name:ident) => {
919 mod_impl_empty_protobuf_raw_codec!(cyfs_base, $name);
920 };
921}
922
923#[macro_export]
924macro_rules! inner_impl_empty_protobuf_raw_codec {
925 ($name:ty, $proto_name:ty) => {
926 crate::mod_impl_empty_protobuf_raw_codec!(crate, $name, $proto_name);
927 };
928
929 ($name:ident) => {
930 crate::mod_impl_empty_protobuf_raw_codec!(crate, $name);
931 };
932}
933
934#[cfg(test)]
935mod test {
936 use crate::*;
937 use ::protobuf::Message;
938 use std::convert::TryFrom;
939
940 #[derive(Clone, Debug, RawEncode, RawDecode)]
942 struct EmptyContent {}
943
944 struct EmptyContent2 {}
945
946 inner_impl_empty_protobuf_raw_codec!(EmptyContent2);
947
948 struct EmptyContentV1 {
949 name: Option<String>,
950 }
951
952 impl TryFrom<protos::EmptyContentV1> for EmptyContentV1 {
953 type Error = BuckyError;
954 fn try_from(mut value: protos::EmptyContentV1) -> BuckyResult<Self> {
955 let mut ret = Self { name: None };
956
957 if value.has_name() {
958 ret.name = Some(value.take_name());
959 }
960
961 Ok(ret)
962 }
963 }
964 impl TryFrom<&EmptyContentV1> for protos::EmptyContentV1 {
965 type Error = BuckyError;
966 fn try_from(value: &EmptyContentV1) -> BuckyResult<Self> {
967 let mut ret = Self::new();
968 if let Some(name) = &value.name {
969 ret.set_name(name.to_owned());
970 }
971
972 Ok(ret)
973 }
974 }
975 inner_impl_default_protobuf_raw_codec!(EmptyContentV1);
976
977 #[test]
978 fn test_protobuf() {
979 {
981 let content = protos::EmptyContent::new();
982 let size = content.compute_size();
983 assert_eq!(size, 0);
984
985 let buf = vec![0u8; 0];
986 let (content_v1, _) = EmptyContentV1::raw_decode(&buf).unwrap();
987 assert!(content_v1.name.is_none());
988 }
989
990 {
992 let content_v1 = EmptyContentV1 {
993 name: Some("xxx".to_owned()),
994 };
995 let buf = content_v1.to_vec().unwrap();
996 assert!(buf.len() > 0);
997
998 let (_content, left_buf) = EmptyContent::raw_decode(&buf).unwrap();
1001 assert!(left_buf.len() == buf.len());
1002
1003 let (_content, left_buf) = EmptyContent2::raw_decode(&buf).unwrap();
1005 assert!(left_buf.len() == 0);
1006 }
1007
1008 let content2 = EmptyContent {};
1009 let buf = content2.to_vec().unwrap();
1010 assert_eq!(buf.len(), 0);
1011 }
1012
1013 #[test]
1014 fn test_helper() {
1015 let mut source: u32 = u32::MAX;
1016 let ret = ProtobufCodecHelper::decode_value::<u8, u32>(source);
1017 assert!(ret.is_err());
1018
1019 source = u8::MAX as u32;
1020 let ret = ProtobufCodecHelper::decode_value::<u8, u32>(source);
1021 assert!(ret.is_ok());
1022 assert_eq!(ret.unwrap(), u8::MAX);
1023 }
1024}