moq_lite/message/
announce.rs

1use num_enum::{IntoPrimitive, TryFromPrimitive};
2
3use crate::{coding::*, Path};
4
5/// Sent by the publisher to announce the availability of a track.
6/// The payload contains the contents of the wildcard.
7#[derive(Clone, Debug, PartialEq, Eq)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub enum Announce<'a> {
10	Active {
11		#[cfg_attr(feature = "serde", serde(borrow))]
12		suffix: Path<'a>,
13	},
14	Ended {
15		#[cfg_attr(feature = "serde", serde(borrow))]
16		suffix: Path<'a>,
17	},
18}
19
20impl<'a> Announce<'a> {
21	pub fn suffix(&self) -> &Path<'a> {
22		match self {
23			Announce::Active { suffix } => suffix,
24			Announce::Ended { suffix } => suffix,
25		}
26	}
27}
28
29impl<'a> Message for Announce<'a> {
30	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
31		Ok(match AnnounceStatus::decode(r)? {
32			AnnounceStatus::Active => Self::Active {
33				suffix: Path::decode(r)?,
34			},
35			AnnounceStatus::Ended => Self::Ended {
36				suffix: Path::decode(r)?,
37			},
38		})
39	}
40
41	fn encode<W: bytes::BufMut>(&self, w: &mut W) {
42		match self {
43			Self::Active { suffix } => {
44				AnnounceStatus::Active.encode(w);
45				suffix.encode(w);
46			}
47			Self::Ended { suffix } => {
48				AnnounceStatus::Ended.encode(w);
49				suffix.encode(w);
50			}
51		}
52	}
53}
54
55/// Sent by the subscriber to request ANNOUNCE messages.
56#[derive(Clone, Debug)]
57pub struct AnnouncePlease<'a> {
58	// Request tracks with this prefix.
59	pub prefix: Path<'a>,
60}
61
62impl<'a> Message for AnnouncePlease<'a> {
63	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
64		let prefix = Path::decode(r)?;
65		Ok(Self { prefix })
66	}
67
68	fn encode<W: bytes::BufMut>(&self, w: &mut W) {
69		self.prefix.encode(w)
70	}
71}
72
73/// Send by the publisher, used to determine the message that follows.
74#[derive(Clone, Copy, Debug, IntoPrimitive, TryFromPrimitive)]
75#[repr(u8)]
76enum AnnounceStatus {
77	Ended = 0,
78	Active = 1,
79}
80
81impl Decode for AnnounceStatus {
82	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
83		let status = u8::decode(r)?;
84		match status {
85			0 => Ok(Self::Ended),
86			1 => Ok(Self::Active),
87			_ => Err(DecodeError::InvalidValue),
88		}
89	}
90}
91
92impl Encode for AnnounceStatus {
93	fn encode<W: bytes::BufMut>(&self, w: &mut W) {
94		(*self as u8).encode(w)
95	}
96}
97
98/// Sent after setup to communicate the initially announced paths.
99#[derive(Clone, Debug, PartialEq, Eq)]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101pub struct AnnounceInit<'a> {
102	/// List of currently active broadcasts, encoded as suffixes to be combined with the prefix.
103	#[cfg_attr(feature = "serde", serde(borrow))]
104	pub suffixes: Vec<Path<'a>>,
105}
106
107impl<'a> Message for AnnounceInit<'a> {
108	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
109		let count = u64::decode(r)?;
110
111		// Don't allocate more than 1024 elements upfront
112		let mut paths = Vec::with_capacity(count.min(1024) as usize);
113
114		for _ in 0..count {
115			paths.push(Path::decode(r)?);
116		}
117
118		Ok(Self { suffixes: paths })
119	}
120
121	fn encode<W: bytes::BufMut>(&self, w: &mut W) {
122		(self.suffixes.len() as u64).encode(w);
123		for path in &self.suffixes {
124			path.encode(w);
125		}
126	}
127}