1use std::io;
2
3use asynchronous_codec::{BytesMut, Decoder, Encoder};
4use unsigned_varint::codec::UviBytes;
5
6pub struct ProtobufUviCodec<M> {
7 uvi_codec: UviBytes,
8 _marker: std::marker::PhantomData<M>,
9}
10
11impl<M> Default for ProtobufUviCodec<M> {
12 fn default() -> Self {
13 ProtobufUviCodec {
14 uvi_codec: UviBytes::default(),
15 _marker: std::marker::PhantomData,
16 }
17 }
18}
19
20impl<M> Clone for ProtobufUviCodec<M> {
21 fn clone(&self) -> Self {
22 let mut uvi = UviBytes::default();
23 uvi.set_max_len(self.uvi_codec.max_len());
24 ProtobufUviCodec {
25 uvi_codec: uvi,
26 _marker: std::marker::PhantomData,
27 }
28 }
29}
30
31impl<M> ProtobufUviCodec<M> {
32 pub fn set_max_len(&mut self, val: usize) {
33 self.uvi_codec.set_max_len(val)
34 }
35
36 pub fn max_len(&self) -> usize {
37 self.uvi_codec.max_len()
38 }
39}
40
41impl<M> Encoder for ProtobufUviCodec<M>
42where
43 M: prost::Message,
44{
45 type Item<'a> = M;
46 type Error = io::Error;
47
48 fn encode(&mut self, item: Self::Item<'_>, dst: &mut BytesMut) -> Result<(), Self::Error> {
49 let len = item.encoded_len();
50 let mut buffer = BytesMut::with_capacity(len);
51 item.encode(&mut buffer)?;
52 self.uvi_codec.encode(buffer.freeze(), dst)
53 }
54}
55
56impl<M> Decoder for ProtobufUviCodec<M>
57where
58 M: prost::Message + Default,
59{
60 type Item = M;
61 type Error = io::Error;
62
63 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
64 match self.uvi_codec.decode(src) {
65 Ok(Some(bytes)) => {
66 let item = M::decode(bytes.as_ref())
67 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
68 Ok(Some(item))
69 }
70 Ok(None) => Ok(None),
71 Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)),
72 }
73 }
74}