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