cyfs_base/codec/protobuf/
protobuf_helper.rs

1use crate::*;
2
3use std::{convert::TryFrom, str::FromStr};
4use std::collections::HashMap;
5
6// 为了读取CodedOutputStream里面的position字段
7// TODO 确保protobuf的版本,如果此结构体发生变化,需要同步,否则会导致读取错误
8mod 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    /// Buffered write with handy utilities
15    pub struct CodedOutputStream<'a> {
16        target: OutputTarget<'a>,
17        // alias to buf from target
18        buffer: &'a mut [u8],
19        // within buffer
20        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        //let stream_exposed: stream_pos_retreve_helper::CodedOutputStream =
51        //    unsafe { std::mem::transmute(stream) };
52
53        Ok(&mut buf[size..])
54    }
55
56    // 需要使用精确长度的buf来decode
57    pub fn raw_decode<'de, T>(buf: &'de [u8]) -> BuckyResult<(T, &'de [u8])>
58    where
59        T: ::protobuf::Message,
60    {
61        // buffer的size就是整个body_content的长度
62        let size = buf.len();
63
64        // 必须截取精确大小的buffer
65        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    // 解码嵌套Message结构
207    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    // 编码到嵌套的Message结构
219    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    // 解码支持嵌套TryFrom的结构体数组
231    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}
326//
327// impl<T> ProtobufTransform<T> for T {
328//     fn transform(value: T) -> BuckyResult<Self> {
329//         Ok(value)
330//     }
331// }
332//
333// impl <T: Clone> ProtobufTransform<&T> for T {
334//     fn transform(value: &T) -> BuckyResult<Self> {
335//         Ok(value.clone())
336//     }
337// }
338
339impl <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
379// impl<T: Into<T>, U> ProtobufTransform<T> for U {
380//     fn transform(value: T) -> BuckyResult<Self> {
381//         Ok(value.into())
382//     }
383// }
384//
385// impl<T, U: ProtobufTransform<T>> ProtobufTransform<Option<T>> for U {
386//     fn transform(value: Option<T>) -> BuckyResult<Self> {
387//         match value {
388//             Some(value) => ProtobufTransform::transform(value),
389//             None => Err(BuckyError::new(BuckyErrorCode::InvalidInput, format!("transform failed. value can't None")))
390//         }
391//     }
392// }
393
394impl<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// impl ProtobufTransform<Vec<i8>> for Vec<i8> {
653//     fn transform(value: Vec<i8>) -> BuckyResult<Self> {
654//         Ok(value)
655//     }
656// }
657//
658// impl ProtobufTransform<&Vec<i8>> for Vec<i8> {
659//     fn transform(value: &Vec<i8>) -> BuckyResult<Self> {
660//         Ok(value.clone())
661//     }
662// }
663//
664// impl ProtobufTransform<Vec<u8>> for Vec<u8> {
665//     fn transform(value: Vec<u8>) -> BuckyResult<Self> {
666//         Ok(value)
667//     }
668// }
669//
670// impl ProtobufTransform<&Vec<u8>> for Vec<u8> {
671//     fn transform(value: &Vec<u8>) -> BuckyResult<Self> {
672//         Ok(value.clone())
673//     }
674// }
675//
676// impl ProtobufTransform<Vec<i16>> for Vec<i16> {
677//     fn transform(value: Vec<i16>) -> BuckyResult<Self> {
678//         Ok(value)
679//     }
680// }
681//
682// impl ProtobufTransform<&Vec<i16>> for Vec<i16> {
683//     fn transform(value: &Vec<i16>) -> BuckyResult<Self> {
684//         Ok(value.clone())
685//     }
686// }
687//
688// impl ProtobufTransform<Vec<u16>> for Vec<u16> {
689//     fn transform(value: Vec<u16>) -> BuckyResult<Self> {
690//         Ok(value)
691//     }
692// }
693//
694// impl ProtobufTransform<&Vec<u16>> for Vec<u16> {
695//     fn transform(value: &Vec<u16>) -> BuckyResult<Self> {
696//         Ok(value.clone())
697//     }
698// }
699//
700// impl ProtobufTransform<Vec<i32>> for Vec<i32> {
701//     fn transform(value: Vec<i32>) -> BuckyResult<Self> {
702//         Ok(value)
703//     }
704// }
705//
706// impl ProtobufTransform<&Vec<i32>> for Vec<i32> {
707//     fn transform(value: &Vec<i32>) -> BuckyResult<Self> {
708//         Ok(value.clone())
709//     }
710// }
711//
712// impl ProtobufTransform<Vec<u32>> for Vec<u32> {
713//     fn transform(value: Vec<u32>) -> BuckyResult<Self> {
714//         Ok(value)
715//     }
716// }
717//
718// impl ProtobufTransform<&Vec<u32>> for Vec<u32> {
719//     fn transform(value: &Vec<u32>) -> BuckyResult<Self> {
720//         Ok(value.clone())
721//     }
722// }
723//
724//
725// impl ProtobufTransform<Vec<i64>> for Vec<i64> {
726//     fn transform(value: Vec<i64>) -> BuckyResult<Self> {
727//         Ok(value)
728//     }
729// }
730//
731// impl ProtobufTransform<&Vec<i64>> for Vec<i64> {
732//     fn transform(value: &Vec<i64>) -> BuckyResult<Self> {
733//         Ok(value.clone())
734//     }
735// }
736//
737// impl ProtobufTransform<Vec<u64>> for Vec<u64> {
738//     fn transform(value: Vec<u64>) -> BuckyResult<Self> {
739//         Ok(value)
740//     }
741// }
742//
743// impl ProtobufTransform<&Vec<u64>> for Vec<u64> {
744//     fn transform(value: &Vec<u64>) -> BuckyResult<Self> {
745//         Ok(value.clone())
746//     }
747// }
748
749/*
750impl<T: ::protobuf::Message> RawEncode for T {
751    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
752        let size = self.compute_size() as usize;
753        Ok(size)
754    }
755
756    fn raw_encode<'a>(
757        &self,
758        buf: &'a mut [u8],
759        purpose: &Option<RawEncodePurpose>,
760    ) -> BuckyResult<&'a mut [u8]> {
761        let mut stream = ::protobuf::CodedOutputStream::bytes(buf);
762        self.write_to(&mut stream).map_err(|e| {
763            let msg = format!("write protobuf::Message to stream error! {}", e);
764            error!("{}", msg);
765
766            BuckyError::new(BuckyErrorCode::OutOfLimit, msg)
767        })?;
768
769        let stream_exposed: stream_pos_retreve_helper::CodedOutputStream = unsafe {
770            std::mem::transmute(stream)
771        };
772
773        Ok(&mut buf[stream_exposed.position..])
774    }
775}
776
777impl<'de, T: ::protobuf::Message> RawDecode<'de> for T {
778    fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
779        todo!();
780    }
781}
782*/
783
784/*
785为某个struct实现基于protobuf的rawcodec编解码,需要满足如下条件
7861. 为结构体{name}定义同名的proto文件,并编译成对应的rust放到相同工程,并且可以通过protos::{name}来引用
7872. 定义{name}和protos::{name}互转的TryFrom,签名如下:
788    impl TryFrom<&{name}> for protos::{name}} {
789        type Error = BuckyError;
790
791        fn try_from(value: &{name}) -> BuckyResult<Self> {
792            ......
793        }
794    }
795
796    impl TryFrom<protos::{name}> for {name} {
797        type Error = BuckyError;
798
799        fn try_from(value: protos::{name}) -> BuckyResult<Self> {
800            ......
801        }
802    }
803*/
804
805#[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                // info!("desc content measure");
814                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                // info!("desc content encode");
822                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                // info!("desc content decode");
828                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// cyfs_base工程内部使用
839#[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                // info!("desc content measure");
848                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                // info!("desc content encode");
856                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                // info!("desc content decode");
862                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// 用以为空结构体实现基于protobuf的编解码
873#[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                // info!("desc content decode");
894
895                let (msg, buf) = $m::ProtobufMessageCodecHelper::raw_decode::<$proto_name>(buf)?;
896
897                // 如果存在unknown fields,那么打印
898                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    // 空结构体可以使用raw_codec,也可以使用protobuf辅助宏来实现
941    #[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        // 新版本兼容老版本
980        {
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        // 老版本兼容新版本
991        {
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            // 如果是使用了默认的rawcodec,那么解码后buf长度不会变化
999            // 但我们在上层object_mut_body实际没使用返回的buf,所以可以完全兼容
1000            let (_content, left_buf) = EmptyContent::raw_decode(&buf).unwrap();
1001            assert!(left_buf.len() == buf.len());
1002
1003            // 如果是使用了protobuf编解码,那么就会消耗掉整个buf
1004            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}