1use bytes::Buf;
2
3use crate::coding::{Decode, DecodeError, Encode};
4
5const SUBGROUP_ID: u8 = 0x0;
6const GROUP_END: u8 = 0x03;
7
8pub struct Group {
9 pub subscribe_id: u64,
10 pub track_alias: u64,
11 pub group_id: u64,
12 pub publisher_priority: u8,
13}
14
15impl Group {
16 pub const STREAM_TYPE: u64 = 0x04;
17}
18
19impl Encode for Group {
20 fn encode<W: bytes::BufMut>(&self, w: &mut W) {
21 self.subscribe_id.encode(w);
22 self.track_alias.encode(w);
23 self.group_id.encode(w);
24 SUBGROUP_ID.encode(w);
25 self.publisher_priority.encode(w);
26 }
27}
28
29impl Decode for Group {
30 fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
31 let subscribe_id = u64::decode(r)?;
32 let track_alias = u64::decode(r)?;
33 let group_id = u64::decode(r)?;
34 let subgroup_id = u8::decode(r)?;
35 if subgroup_id != SUBGROUP_ID {
36 return Err(DecodeError::InvalidValue);
37 }
38 let publisher_priority = u8::decode(r)?;
39 Ok(Self {
40 subscribe_id,
41 track_alias,
42 group_id,
43 publisher_priority,
44 })
45 }
46}
47
48pub struct Frame {
49 pub id: u64,
50 pub payload: Option<Vec<u8>>,
51}
52
53impl Encode for Frame {
54 fn encode<W: bytes::BufMut>(&self, w: &mut W) {
55 self.id.encode(w);
56
57 let size = self.payload.as_ref().map(|p| p.len()).unwrap_or(0);
58 size.encode(w);
59
60 match &self.payload {
61 Some(payload) if !payload.is_empty() => w.put_slice(payload),
62 Some(_) => 0u8.encode(w),
63 None => GROUP_END.encode(w),
64 }
65 }
66}
67
68impl Decode for Frame {
69 fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
70 let id = u64::decode(r)?;
71 let size = u64::decode(r)?;
72
73 if r.remaining() < size as usize {
74 return Err(DecodeError::Short);
75 }
76
77 if size > 0 {
78 let payload = r.copy_to_bytes(size as usize).to_vec();
79 Ok(Self {
80 id,
81 payload: Some(payload),
82 })
83 } else {
84 match u8::decode(r)? {
85 0 => Ok(Self {
86 id,
87 payload: Some(Vec::new()),
88 }),
89 GROUP_END => Ok(Self { id, payload: None }),
90 _ => Err(DecodeError::InvalidValue),
91 }
92 }
93 }
94}