use crate::varint::VarInt;
use bytes::{Buf, BufMut};
#[inline]
#[allow(clippy::uninit_vec)]
pub fn read_bytes(buf: &mut impl Buf, len: usize) -> Result<Vec<u8>, crate::error::CodecError> {
if buf.remaining() < len {
return Err(crate::error::CodecError::UnexpectedEnd);
}
let mut v = Vec::with_capacity(len);
unsafe {
v.set_len(len);
}
buf.copy_to_slice(&mut v);
Ok(v)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TrackNamespace(pub Vec<Vec<u8>>);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FullTrackName {
pub namespace: TrackNamespace,
pub track_name: Vec<u8>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Location {
pub group: VarInt,
pub object: VarInt,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum ObjectStatus {
Normal = 0x0,
EndOfGroup = 0x1,
EndOfTrack = 0x2,
DoesNotExist = 0x3,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum GroupOrder {
Publisher = 0x0,
Ascending = 0x1,
Descending = 0x2,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum ForwardingPreference {
Object = 0x0,
Datagram = 0x1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum ContentExists {
NoLargestLocation = 0,
HasLargestLocation = 1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Forward {
DontForward = 0,
Forward = 1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum FilterType {
NextGroupStart = 0x1,
LargestObject = 0x2,
AbsoluteStart = 0x3,
AbsoluteRange = 0x4,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum TokenAliasType {
Delete = 0x0,
Register = 0x1,
UseAlias = 0x2,
UseValue = 0x3,
}
impl TrackNamespace {
pub fn encode(&self, buf: &mut impl BufMut) {
VarInt::from_usize(self.0.len()).encode(buf);
for elem in &self.0 {
VarInt::from_usize(elem.len()).encode(buf);
buf.put_slice(elem);
}
}
pub fn decode(buf: &mut impl Buf) -> Result<Self, crate::error::CodecError> {
let n = VarInt::decode(buf)?.into_inner() as usize;
if n == 0 || n > crate::error::MAX_NAMESPACE_TUPLE_SIZE {
return Err(crate::error::CodecError::InvalidNamespaceTupleSize(n));
}
Self::decode_elements(buf, n)
}
pub fn decode_allow_empty(buf: &mut impl Buf) -> Result<Self, crate::error::CodecError> {
let n = VarInt::decode(buf)?.into_inner() as usize;
if n > crate::error::MAX_NAMESPACE_TUPLE_SIZE {
return Err(crate::error::CodecError::InvalidNamespaceTupleSize(n));
}
Self::decode_elements(buf, n)
}
fn decode_elements(buf: &mut impl Buf, n: usize) -> Result<Self, crate::error::CodecError> {
let mut elements = Vec::with_capacity(n);
for _ in 0..n {
let len = VarInt::decode(buf)?.into_inner() as usize;
elements.push(read_bytes(buf, len)?);
}
Ok(TrackNamespace(elements))
}
}
impl Location {
pub fn encode(&self, buf: &mut impl BufMut) {
self.group.encode(buf);
self.object.encode(buf);
}
pub fn decode(buf: &mut impl Buf) -> Result<Self, crate::error::CodecError> {
let group = VarInt::decode(buf)?;
let object = VarInt::decode(buf)?;
Ok(Location { group, object })
}
}
impl ObjectStatus {
pub fn from_u8(v: u8) -> Option<Self> {
match v {
0x0 => Some(ObjectStatus::Normal),
0x1 => Some(ObjectStatus::EndOfGroup),
0x2 => Some(ObjectStatus::EndOfTrack),
0x3 => Some(ObjectStatus::DoesNotExist),
_ => None,
}
}
}
impl GroupOrder {
pub fn from_u8(v: u8) -> Option<Self> {
match v {
0x0 => Some(GroupOrder::Publisher),
0x1 => Some(GroupOrder::Ascending),
0x2 => Some(GroupOrder::Descending),
_ => None,
}
}
}
impl ForwardingPreference {
pub fn from_u8(v: u8) -> Option<Self> {
match v {
0x0 => Some(ForwardingPreference::Object),
0x1 => Some(ForwardingPreference::Datagram),
_ => None,
}
}
}
impl FilterType {
pub fn from_u8(v: u8) -> Option<Self> {
Self::from_u64(v as u64)
}
pub fn from_u64(v: u64) -> Option<Self> {
match v {
0x1 => Some(FilterType::NextGroupStart),
0x2 => Some(FilterType::LargestObject),
0x3 => Some(FilterType::AbsoluteStart),
0x4 => Some(FilterType::AbsoluteRange),
_ => None,
}
}
}