saddle-boundary 0.3.29

Saddle 0.3 ProfuseContract unary boundary transport
//! Carry independently prepaid protobuf storage into tonic's encoder. The
//! encoder owns the bill with the value; no detached lifetime/early refund.
use crate::{InvokeRequest, InvokeResponse};
use prost::Message;
use saddle_admission::ReadOnlyInput;
use tonic::codec::{Codec, EncodeBuf, Encoder, ProstCodec};

pub(crate) enum Request {
    Legacy(InvokeRequest),
    Metered(ReadOnlyInput<InvokeRequest>),
}
impl From<InvokeRequest> for Request {
    fn from(value: InvokeRequest) -> Self { Self::Legacy(value) }
}
impl From<ReadOnlyInput<InvokeRequest>> for Request {
    fn from(value: ReadOnlyInput<InvokeRequest>) -> Self { Self::Metered(value) }
}
impl std::ops::Deref for Request {
    type Target = InvokeRequest;
    fn deref(&self) -> &InvokeRequest {
        match self { Self::Legacy(value) => value, Self::Metered(value) => value.get() }
    }
}
pub(crate) struct WireCodec;
pub(crate) struct WireEncoder;
impl Codec for WireCodec {
    type Encode = Request;
    type Decode = InvokeResponse;
    type Encoder = WireEncoder;
    type Decoder = <ProstCodec<InvokeRequest, InvokeResponse> as Codec>::Decoder;
    fn encoder(&mut self) -> Self::Encoder { WireEncoder }
    fn decoder(&mut self) -> Self::Decoder {
        ProstCodec::<InvokeRequest, InvokeResponse>::default().decoder()
    }
}
impl Encoder for WireEncoder {
    type Item = Request;
    type Error = tonic::Status;
    fn encode(&mut self, item: Request, buffer: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
        // Tonic owns its private encoded output buffer under the existing
        // dependency boundary. Our native fields remain billed until dropped.
        item.encode(buffer).map_err(|_| tonic::Status::internal("protobuf encode capacity"))
    }
}