Files
crank/crates/mcpaas-adapter-grpc/src/codec.rs
T
2026-03-25 21:23:57 +03:00

73 lines
1.8 KiB
Rust

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()))
}
}