use std::time;
use crate::coding::{DecodeError, EncodeError, VarInt};
use crate::coding::{AsyncRead, AsyncWrite};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[derive(Clone, Debug)]
pub struct Object {
pub track: VarInt,
pub sequence: VarInt,
pub priority: i32,
pub expires: Option<time::Duration>,
}
impl Object {
pub async fn decode<R: AsyncRead>(r: &mut R) -> Result<Self, DecodeError> {
let typ = VarInt::decode(r).await?;
if typ.into_inner() != 0 {
return Err(DecodeError::InvalidType(typ));
}
let track = VarInt::decode(r).await?;
let sequence = VarInt::decode(r).await?;
let priority = r.read_i32().await?; let expires = match VarInt::decode(r).await?.into_inner() {
0 => None,
secs => Some(time::Duration::from_secs(secs)),
};
Ok(Self {
track,
sequence,
priority,
expires,
})
}
pub async fn encode<W: AsyncWrite>(&self, w: &mut W) -> Result<(), EncodeError> {
VarInt::ZERO.encode(w).await?;
self.track.encode(w).await?;
self.sequence.encode(w).await?;
w.write_i32(self.priority).await?;
let expires = match self.expires {
None => 0,
Some(time::Duration::ZERO) => return Err(EncodeError::InvalidValue), Some(expires) if expires.subsec_nanos() > 0 => expires.as_secs() + 1,
Some(expires) => expires.as_secs(),
};
VarInt::try_from(expires)?.encode(w).await?;
Ok(())
}
}