use std::marker::PhantomData;
use bytes::BytesMut;
use serde::Serialize;
use super::{Outgoing, OutgoingName, Payload, Serialized, WireBytes};
use crate::codec::{Codec, CodecError};
use crate::{HeaderMap, Lend, OutgoingMessage, PayloadForm, Take};
#[inline]
fn kept<'a>(name: OutgoingName<'a>, slot: &'a mut Option<OutgoingName<'static>>) -> &'a str {
match name {
OutgoingName::Borrowed(name) => name,
OutgoingName::Owned(name) => slot.insert(OutgoingName::Owned(name)).as_str(),
OutgoingName::Shared(name) => slot.insert(OutgoingName::Shared(name)).as_str(),
}
}
impl PayloadForm for Lend {
type Form<'a> = &'a [u8];
type Encode<'a> = &'a mut BytesMut;
type Spent = (Option<OutgoingName<'static>>, Option<BytesMut>);
#[inline]
fn encode_slot(buf: &mut BytesMut) -> &mut BytesMut {
buf
}
#[allow(clippy::mut_mut)]
#[inline]
fn encode_again<'s, 'a: 's>(slot: &'s mut &'a mut BytesMut) -> &'s mut BytesMut {
slot
}
#[inline]
fn encoded<'b, C, T>(
codec: &C,
value: &T,
buf: Self::Encode<'b>,
) -> Result<Self::Form<'b>, CodecError>
where
C: Codec,
T: Serialize,
{
buf.clear();
codec.encode_into(value, buf)?;
Ok(&buf[..])
}
#[inline]
fn serialized<'v, T>(value: &'v T, buf: Self::Encode<'v>) -> Result<Self::Form<'v>, T::Error>
where
T: Serialized,
{
buf.clear();
Ok(value.wire_bytes(buf)?.of(buf))
}
#[inline]
fn rebuilt<'a>(name: OutgoingName<'a>, payload: &'a [u8], headers: HeaderMap) -> Outgoing<'a> {
Outgoing::rebuilding(name, Payload::Lent(payload), headers)
}
#[inline]
fn leaving<'a>(out: &'a mut Outgoing<'a>) -> OutgoingMessage<'a, &'a [u8]> {
let headers = out.take_headers();
let out: &'a Outgoing<'a> = out;
OutgoingMessage::assembled(out.name(), out.payload(), headers)
}
#[inline]
fn handed_on<'a>(
out: Outgoing<'a>,
spent: &'a mut Self::Spent,
) -> OutgoingMessage<'a, &'a [u8]> {
let (name, payload, headers) = out.into_parts();
let (kept_name, kept_buffer) = spent;
let bytes = match payload {
Payload::Lent(bytes) => bytes,
Payload::Owned(buf) => &kept_buffer.insert(buf)[..],
};
OutgoingMessage::assembled(kept(name, kept_name), bytes, headers)
}
}
impl PayloadForm for Take {
type Form<'a> = BytesMut;
type Encode<'a> = PhantomData<&'a mut BytesMut>;
type Spent = Option<OutgoingName<'static>>;
#[inline]
fn encode_slot(_buf: &mut BytesMut) -> PhantomData<&mut BytesMut> {
PhantomData
}
#[inline]
fn encode_again<'s, 'a: 's>(
_slot: &'s mut PhantomData<&'a mut BytesMut>,
) -> PhantomData<&'s mut BytesMut> {
PhantomData
}
#[inline]
fn encoded<'b, C, T>(
codec: &C,
value: &T,
_buf: Self::Encode<'b>,
) -> Result<Self::Form<'b>, CodecError>
where
C: Codec,
T: Serialize,
{
codec.encode(value)
}
#[inline]
fn serialized<'v, T>(value: &'v T, _buf: Self::Encode<'v>) -> Result<Self::Form<'v>, T::Error>
where
T: Serialized,
{
let mut buf = BytesMut::new();
match value.wire_bytes(&mut buf)? {
WireBytes::InBuffer => Ok(buf),
WireBytes::Own(bytes) => Ok(BytesMut::from(bytes)),
}
}
#[inline]
fn rebuilt(name: OutgoingName<'_>, payload: BytesMut, headers: HeaderMap) -> Outgoing<'_> {
Outgoing::rebuilding(name, Payload::Owned(payload), headers)
}
#[inline]
fn leaving<'a>(out: &'a mut Outgoing<'a>) -> OutgoingMessage<'a, BytesMut> {
let payload = out.take_payload();
let headers = out.take_headers();
OutgoingMessage::assembled(out.name(), payload, headers)
}
#[inline]
fn handed_on<'a>(
out: Outgoing<'a>,
spent: &'a mut Self::Spent,
) -> OutgoingMessage<'a, BytesMut> {
let (name, payload, headers) = out.into_parts();
let payload = match payload {
Payload::Lent(bytes) => BytesMut::from(bytes),
Payload::Owned(buf) => buf,
};
OutgoingMessage::assembled(kept(name, spent), payload, headers)
}
}