poem_grpc/codec/
prost_codec.rs

1use std::{
2    io::{Error, Result},
3    marker::PhantomData,
4};
5
6use bytes::BytesMut;
7use prost::Message;
8
9use crate::codec::{Codec, Decoder, Encoder};
10
11/// A [`Codec`] for Protobuf `application/grpc+proto`
12#[derive(Debug)]
13pub struct ProstCodec<T, U>(PhantomData<(T, U)>);
14
15impl<T, U> Default for ProstCodec<T, U> {
16    fn default() -> Self {
17        Self(PhantomData)
18    }
19}
20
21impl<T, U> Codec for ProstCodec<T, U>
22where
23    T: Message + Send + 'static,
24    U: Message + Default + Send + 'static,
25{
26    const CONTENT_TYPES: &'static [&'static str] = &["application/grpc", "application/grpc+proto"];
27
28    type Encode = T;
29    type Decode = U;
30    type Encoder = ProstEncoder<T>;
31    type Decoder = ProstDecoder<U>;
32
33    fn encoder(&mut self) -> Self::Encoder {
34        ProstEncoder(PhantomData)
35    }
36
37    fn decoder(&mut self) -> Self::Decoder {
38        ProstDecoder(PhantomData)
39    }
40}
41
42#[doc(hidden)]
43pub struct ProstEncoder<T>(PhantomData<T>);
44
45impl<T> Encoder for ProstEncoder<T>
46where
47    T: Message + Send + 'static,
48{
49    type Item = T;
50
51    fn encode(&mut self, message: Self::Item, buf: &mut BytesMut) -> Result<()> {
52        message.encode(buf).map_err(Error::other)
53    }
54}
55
56#[doc(hidden)]
57pub struct ProstDecoder<U>(PhantomData<U>);
58
59impl<U> Decoder for ProstDecoder<U>
60where
61    U: Message + Default + Send + 'static,
62{
63    type Item = U;
64
65    fn decode(&mut self, buf: &[u8]) -> Result<Self::Item> {
66        U::decode(buf).map_err(Error::other)
67    }
68}