saddle-boundary 0.3.37

Saddle 0.3 ProfuseContract unary boundary transport
//! Only raw immutable standard wire is encoded by the dependency driver. Native
//! response storage is prepaid in the original account before copying bytes.
use prost::bytes::{Buf, BufMut};
use saddle_admission::{AdmissionError, ReadOnlyInput, RequestMemory};
use tonic::codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder};

pub(crate) type Response = Result<ReadOnlyInput<Vec<u8>>, AdmissionError>;
pub(crate) struct WireCodec {
    pub memory: RequestMemory,
}
pub(crate) struct WireEncoder;
pub(crate) struct WireDecoder {
    memory: RequestMemory,
}
impl Codec for WireCodec {
    type Encode = ReadOnlyInput<Vec<u8>>;
    type Decode = Response;
    type Encoder = WireEncoder;
    type Decoder = WireDecoder;
    fn encoder(&mut self) -> Self::Encoder {
        WireEncoder
    }
    fn decoder(&mut self) -> Self::Decoder {
        WireDecoder {
            memory: self.memory.clone(),
        }
    }
}
impl Encoder for WireEncoder {
    type Item = ReadOnlyInput<Vec<u8>>;
    type Error = tonic::Status;
    fn encode(&mut self, item: Self::Item, buffer: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
        buffer.put_slice(item.get());
        // item is destroyed only after the encoder no longer reads its fields.
        Ok(())
    }
}
impl Decoder for WireDecoder {
    type Item = Response;
    type Error = tonic::Status;
    fn decode(&mut self, buffer: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
        let len = buffer.remaining();
        let result = self.memory.framework_output(|builder| {
            builder.write_bytes(len, |target| {
                buffer.copy_to_slice(target);
                Ok(())
            })
        });
        // Resource failure is returned intact to the outer original-source
        // recorder; converting it to tonic::Status would discard its identity.
        Ok(Some(result))
    }
}

// Leased wire/codec holders retain operation credit through their actual
// destruction. Only raw framework bytes enter this codec; no business callback.
pub(crate) struct LeasedWire {
    pub wire: ReadOnlyInput<Vec<u8>>,
    pub stage: saddle_admission::RpcStagePermit,
}
pub(crate) struct LeasedCodec {
    pub memory: RequestMemory,
    pub stage: saddle_admission::RpcStagePermit,
}
pub(crate) struct LeasedDecoder {
    memory: RequestMemory,
    stage: Result<saddle_admission::RpcStagePermit, AdmissionError>,
}
pub(crate) struct LeasedEncoder;
impl Codec for LeasedCodec {
    type Encode = LeasedWire;
    type Decode = Response;
    type Encoder = LeasedEncoder;
    type Decoder = LeasedDecoder;
    fn encoder(&mut self) -> Self::Encoder { LeasedEncoder }
    fn decoder(&mut self) -> Self::Decoder {
        LeasedDecoder { memory: self.memory.clone(), stage: self.stage.retain_physical_owner() }
    }
}
impl Encoder for LeasedEncoder {
    type Item = LeasedWire;
    type Error = tonic::Status;
    fn encode(&mut self, item: Self::Item, buffer: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
        buffer.put_slice(item.wire.get());
        // Field order drops immutable wire before its physical operation owner.
        Ok(())
    }
}
impl Decoder for LeasedDecoder {
    type Item = Response;
    type Error = tonic::Status;
    fn decode(&mut self, buffer: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
        if let Err(error) = self.stage { return Ok(Some(Err(error))); }
        let len = buffer.remaining();
        Ok(Some(self.memory.framework_output(|builder| builder.write_bytes(len, |target| {
            buffer.copy_to_slice(target); Ok(())
        }))))
    }
}