use crate::{
cid::{be_connection_id, ConnectionId, WriteConnectionId},
token::{be_reset_token, ResetToken, RESET_TOKEN_SIZE},
varint::{be_varint, VarInt, WriteVarInt},
};
const NEW_CONNECTION_ID_FRAME_TYPE: u8 = 0x18;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NewConnectionIdFrame {
pub sequence: VarInt,
pub retire_prior_to: VarInt,
pub id: ConnectionId,
pub reset_token: ResetToken,
}
impl NewConnectionIdFrame {
pub fn new(cid: ConnectionId, sequence: VarInt, retire_prior_to: VarInt) -> Self {
let reset_token = ResetToken::random_gen();
Self {
sequence,
retire_prior_to,
id: cid,
reset_token,
}
}
}
impl super::BeFrame for NewConnectionIdFrame {
fn frame_type(&self) -> super::FrameType {
super::FrameType::NewConnectionId
}
fn max_encoding_size(&self) -> usize {
1 + 8 + 8 + 21 + RESET_TOKEN_SIZE
}
fn encoding_size(&self) -> usize {
1 + self.sequence.encoding_size()
+ self.retire_prior_to.encoding_size()
+ 1
+ self.id.len as usize
+ RESET_TOKEN_SIZE
}
}
pub fn be_new_connection_id_frame(input: &[u8]) -> nom::IResult<&[u8], NewConnectionIdFrame> {
let (remain, sequence) = be_varint(input)?;
let (remain, retire_prior_to) = be_varint(remain)?;
if retire_prior_to > sequence {
return Err(nom::Err::Error(nom::error::make_error(
input,
nom::error::ErrorKind::Verify,
)));
}
let (remain, cid) = be_connection_id(remain)?;
if cid.len() == 0 {
return Err(nom::Err::Error(nom::error::make_error(
input,
nom::error::ErrorKind::Verify,
)));
}
let (remain, reset_token) = be_reset_token(remain)?;
Ok((
remain,
NewConnectionIdFrame {
sequence,
retire_prior_to,
id: cid,
reset_token,
},
))
}
impl<T: bytes::BufMut> super::io::WriteFrame<NewConnectionIdFrame> for T {
fn put_frame(&mut self, frame: &NewConnectionIdFrame) {
self.put_u8(NEW_CONNECTION_ID_FRAME_TYPE);
self.put_varint(&frame.sequence);
self.put_varint(&frame.retire_prior_to);
self.put_connection_id(&frame.id);
self.put_slice(&frame.reset_token);
}
}