use crate::{frame::Tag, stream::StreamType, varint::VarInt};
use s2n_codec::{decoder_invariant, decoder_parameterized_value, Encoder, EncoderValue};
macro_rules! streams_blocked_tag {
() => {
0x16u8..=0x17u8
};
}
const BIDIRECTIONAL_TAG: u8 = 0x16;
const UNIDIRECTIONAL_TAG: u8 = 0x17;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct StreamsBlocked {
pub stream_type: StreamType,
pub stream_limit: VarInt,
}
impl StreamsBlocked {
pub fn tag(&self) -> u8 {
match self.stream_type {
StreamType::Bidirectional => BIDIRECTIONAL_TAG,
StreamType::Unidirectional => UNIDIRECTIONAL_TAG,
}
}
}
decoder_parameterized_value!(
impl<'a> StreamsBlocked {
fn decode(tag: Tag, buffer: Buffer) -> Result<Self> {
let stream_type = if BIDIRECTIONAL_TAG == tag {
StreamType::Bidirectional
} else {
StreamType::Unidirectional
};
let (stream_limit, buffer) = buffer.decode::<VarInt>()?;
decoder_invariant!(
*stream_limit <= 2u64.pow(60),
"maximum streams cannot exceed 2^60"
);
let frame = StreamsBlocked {
stream_type,
stream_limit,
};
Ok((frame, buffer))
}
}
);
impl EncoderValue for StreamsBlocked {
fn encode<E: Encoder>(&self, buffer: &mut E) {
buffer.encode(&self.tag());
buffer.encode(&self.stream_limit);
}
}