feat: add grpc support
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
use prost::Message;
|
||||
use prost_reflect::{DynamicMessage, MessageDescriptor};
|
||||
use tonic::{
|
||||
Status,
|
||||
codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder},
|
||||
};
|
||||
|
||||
pub struct JsonCodec {
|
||||
request_descriptor: MessageDescriptor,
|
||||
response_descriptor: MessageDescriptor,
|
||||
}
|
||||
|
||||
impl JsonCodec {
|
||||
pub fn new(
|
||||
request_descriptor: MessageDescriptor,
|
||||
response_descriptor: MessageDescriptor,
|
||||
) -> Self {
|
||||
Self {
|
||||
request_descriptor,
|
||||
response_descriptor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Codec for JsonCodec {
|
||||
type Encode = serde_json::Value;
|
||||
type Decode = serde_json::Value;
|
||||
|
||||
type Encoder = JsonEncoder;
|
||||
type Decoder = JsonDecoder;
|
||||
|
||||
fn encoder(&mut self) -> Self::Encoder {
|
||||
JsonEncoder(self.request_descriptor.clone())
|
||||
}
|
||||
|
||||
fn decoder(&mut self) -> Self::Decoder {
|
||||
JsonDecoder(self.response_descriptor.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct JsonEncoder(MessageDescriptor);
|
||||
|
||||
impl Encoder for JsonEncoder {
|
||||
type Item = serde_json::Value;
|
||||
type Error = Status;
|
||||
|
||||
fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
|
||||
let message = DynamicMessage::deserialize(self.0.clone(), item)
|
||||
.map_err(|error| Status::invalid_argument(error.to_string()))?;
|
||||
|
||||
message.encode_raw(dst);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct JsonDecoder(MessageDescriptor);
|
||||
|
||||
impl Decoder for JsonDecoder {
|
||||
type Item = serde_json::Value;
|
||||
type Error = Status;
|
||||
|
||||
fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
|
||||
let mut message = DynamicMessage::new(self.0.clone());
|
||||
message
|
||||
.merge(src)
|
||||
.map_err(|error| Status::internal(error.to_string()))?;
|
||||
|
||||
serde_json::to_value(&message)
|
||||
.map(Some)
|
||||
.map_err(|error| Status::internal(error.to_string()))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user