Skip to main content

moq_transport/message/
subscribe_ok.rs

1use crate::coding::{Decode, DecodeError, Encode, EncodeError, KeyValuePairs, Location};
2use crate::message::GroupOrder;
3
4/// Sent by the publisher to accept a Subscribe.
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub struct SubscribeOk {
7    /// The request ID of the SUBSCRIBE this message is replying to
8    pub id: u64,
9
10    /// The identifier used for this track in Subgroups or Datagrams.
11    pub track_alias: u64,
12
13    /// The time in milliseconds after which the subscription is not longer valid.
14    pub expires: u64,
15
16    /// Order groups will be delivered in
17    pub group_order: GroupOrder,
18
19    /// If content_exists, then largest_location is the location of the largest
20    /// object available for this track
21    pub content_exists: bool,
22    pub largest_location: Option<Location>, // Only provided if content_exists is 1/true
23
24    /// Subscribe Parameters
25    pub params: KeyValuePairs,
26}
27
28impl Decode for SubscribeOk {
29    fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
30        let id = u64::decode(r)?;
31        let track_alias = u64::decode(r)?;
32        let expires = u64::decode(r)?;
33        let group_order = GroupOrder::decode(r)?;
34        let content_exists = bool::decode(r)?;
35        let largest_location = match content_exists {
36            true => Some(Location::decode(r)?),
37            false => None,
38        };
39        let params = KeyValuePairs::decode(r)?;
40
41        Ok(Self {
42            id,
43            track_alias,
44            expires,
45            group_order,
46            content_exists,
47            largest_location,
48            params,
49        })
50    }
51}
52
53impl Encode for SubscribeOk {
54    fn encode<W: bytes::BufMut>(&self, w: &mut W) -> Result<(), EncodeError> {
55        self.id.encode(w)?;
56        self.track_alias.encode(w)?;
57        self.expires.encode(w)?;
58        self.group_order.encode(w)?;
59        self.content_exists.encode(w)?;
60        if self.content_exists {
61            if let Some(largest) = &self.largest_location {
62                largest.encode(w)?;
63            } else {
64                return Err(EncodeError::MissingField("LargestLocation".to_string()));
65            }
66        }
67        self.params.encode(w)?;
68
69        Ok(())
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use bytes::BytesMut;
77
78    #[test]
79    fn encode_decode() {
80        let mut buf = BytesMut::new();
81
82        // One parameter for testing
83        let mut kvps = KeyValuePairs::new();
84        kvps.set_bytesvalue(123, vec![0x00, 0x01, 0x02, 0x03]);
85
86        let msg = SubscribeOk {
87            id: 12345,
88            track_alias: 100,
89            expires: 3600,
90            group_order: GroupOrder::Publisher,
91            content_exists: true,
92            largest_location: Some(Location::new(2, 3)),
93            params: kvps.clone(),
94        };
95        msg.encode(&mut buf).unwrap();
96        let decoded = SubscribeOk::decode(&mut buf).unwrap();
97        assert_eq!(decoded, msg);
98    }
99
100    #[test]
101    fn encode_missing_fields() {
102        let mut buf = BytesMut::new();
103
104        let msg = SubscribeOk {
105            id: 12345,
106            track_alias: 100,
107            expires: 3600,
108            group_order: GroupOrder::Publisher,
109            content_exists: true,
110            largest_location: None,
111            params: Default::default(),
112        };
113        let encoded = msg.encode(&mut buf);
114        assert!(matches!(encoded.unwrap_err(), EncodeError::MissingField(_)));
115    }
116}