-
Notifications
You must be signed in to change notification settings - Fork 0
/
codec.rs
60 lines (49 loc) · 1.47 KB
/
codec.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use prost_reflect::prost::Message;
use prost_reflect::{DynamicMessage, MethodDescriptor, ReflectMessage};
use tonic::{
codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder},
Status,
};
use crate::grpc;
#[derive(Debug, Clone)]
pub struct DynamicCodec(MethodDescriptor);
impl DynamicCodec {
pub fn new(desc: MethodDescriptor) -> Self {
DynamicCodec(desc)
}
}
impl Codec for DynamicCodec {
type Encode = grpc::Request;
type Decode = grpc::Response;
type Encoder = DynamicCodec;
type Decoder = DynamicCodec;
fn encoder(&mut self) -> Self::Encoder {
self.clone()
}
fn decoder(&mut self) -> Self::Decoder {
self.clone()
}
}
impl Encoder for DynamicCodec {
type Item = grpc::Request;
type Error = Status;
fn encode(&mut self, request: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
debug_assert_eq!(request.message.descriptor(), self.0.input());
request
.message
.encode(dst)
.expect("insufficient space for message");
Ok(())
}
}
impl Decoder for DynamicCodec {
type Item = grpc::Response;
type Error = Status;
fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
let mut message = DynamicMessage::new(self.0.output());
message
.merge(src)
.map_err(|err| Status::internal(err.to_string()))?;
Ok(Some(grpc::Response::new(message)))
}
}