|
| 1 | +//! This module defines common request/response types as well as the JsonCodec that is used by the |
| 2 | +//! json.helloworld.Greeter service which is defined manually (instead of via proto files) by the |
| 3 | +//! `build_json_codec_service` function in the `examples/build.rs` file. |
| 4 | +
|
| 5 | +use bytes::{Buf, BufMut}; |
| 6 | +use serde::{Deserialize, Serialize}; |
| 7 | +use std::marker::PhantomData; |
| 8 | +use tonic::{ |
| 9 | + codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder}, |
| 10 | + Status, |
| 11 | +}; |
| 12 | + |
| 13 | +#[derive(Debug, Deserialize, Serialize)] |
| 14 | +pub struct HelloRequest { |
| 15 | + pub name: String, |
| 16 | +} |
| 17 | + |
| 18 | +#[derive(Debug, Deserialize, Serialize)] |
| 19 | +pub struct HelloResponse { |
| 20 | + pub message: String, |
| 21 | +} |
| 22 | + |
| 23 | +#[derive(Debug)] |
| 24 | +pub struct JsonEncoder<T>(PhantomData<T>); |
| 25 | + |
| 26 | +impl<T: serde::Serialize> Encoder for JsonEncoder<T> { |
| 27 | + type Item = T; |
| 28 | + type Error = Status; |
| 29 | + |
| 30 | + fn encode(&mut self, item: Self::Item, buf: &mut EncodeBuf<'_>) -> Result<(), Self::Error> { |
| 31 | + serde_json::to_writer(buf.writer(), &item).map_err(|e| Status::internal(e.to_string())) |
| 32 | + } |
| 33 | +} |
| 34 | + |
| 35 | +#[derive(Debug)] |
| 36 | +pub struct JsonDecoder<U>(PhantomData<U>); |
| 37 | + |
| 38 | +impl<U: serde::de::DeserializeOwned> Decoder for JsonDecoder<U> { |
| 39 | + type Item = U; |
| 40 | + type Error = Status; |
| 41 | + |
| 42 | + fn decode(&mut self, buf: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> { |
| 43 | + if !buf.has_remaining() { |
| 44 | + return Ok(None); |
| 45 | + } |
| 46 | + |
| 47 | + let item: Self::Item = |
| 48 | + serde_json::from_reader(buf.reader()).map_err(|e| Status::internal(e.to_string()))?; |
| 49 | + Ok(Some(item)) |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +/// A [`Codec`] that implements `application/grpc+json` via the serde library. |
| 54 | +#[derive(Debug, Clone)] |
| 55 | +pub struct JsonCodec<T, U>(PhantomData<(T, U)>); |
| 56 | + |
| 57 | +impl<T, U> Default for JsonCodec<T, U> { |
| 58 | + fn default() -> Self { |
| 59 | + Self(PhantomData) |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +impl<T, U> Codec for JsonCodec<T, U> |
| 64 | +where |
| 65 | + T: serde::Serialize + Send + 'static, |
| 66 | + U: serde::de::DeserializeOwned + Send + 'static, |
| 67 | +{ |
| 68 | + type Encode = T; |
| 69 | + type Decode = U; |
| 70 | + type Encoder = JsonEncoder<T>; |
| 71 | + type Decoder = JsonDecoder<U>; |
| 72 | + |
| 73 | + fn encoder(&mut self) -> Self::Encoder { |
| 74 | + JsonEncoder(PhantomData) |
| 75 | + } |
| 76 | + |
| 77 | + fn decoder(&mut self) -> Self::Decoder { |
| 78 | + JsonDecoder(PhantomData) |
| 79 | + } |
| 80 | +} |
0 commit comments