Skip to main content

moq_transport/setup/
version.rs

1use crate::coding::{Decode, DecodeError, Encode, EncodeError, VarInt};
2
3use std::fmt;
4use std::ops::Deref;
5
6/// A version number negotiated during the setup.
7#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct Version(pub u32);
9
10impl Version {
11    // Note: older draft versions are NOT included here, as we will no longer
12    //       handle the old SETUP message type numbers of (0x40 and 0x41)
13
14    /// First version we might see in CLIENT_SETUP (0x20) or SERVER_SETUP (0x21)
15    /// https://www.ietf.org/archive/id/draft-ietf-moq-transport-11.html
16    pub const DRAFT_11: Version = Version(0xff00000b);
17
18    /// https://www.ietf.org/archive/id/draft-ietf-moq-transport-12.html
19    pub const DRAFT_12: Version = Version(0xff00000c);
20
21    /// https://www.ietf.org/archive/id/draft-ietf-moq-transport-13.html
22    pub const DRAFT_13: Version = Version(0xff00000d);
23
24    /// https://www.ietf.org/archive/id/draft-ietf-moq-transport-14.html
25    pub const DRAFT_14: Version = Version(0xff00000e);
26}
27
28impl From<u32> for Version {
29    fn from(v: u32) -> Self {
30        Self(v)
31    }
32}
33
34impl From<Version> for u32 {
35    fn from(v: Version) -> Self {
36        v.0
37    }
38}
39
40impl Decode for Version {
41    /// Decode the version number.
42    fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
43        let v = VarInt::decode(r)?;
44        Ok(Self(u32::try_from(v).map_err(DecodeError::BoundsExceeded)?))
45    }
46}
47
48impl Encode for Version {
49    fn encode<W: bytes::BufMut>(&self, w: &mut W) -> Result<(), EncodeError> {
50        VarInt::from_u32(self.0).encode(w)?;
51        Ok(())
52    }
53}
54
55impl fmt::Debug for Version {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        // Just reuse the Display formatting
58        write!(f, "{self}")
59    }
60}
61
62impl fmt::Display for Version {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        if self.0 > 0xff000000 {
65            write!(f, "DRAFT_{:02}", self.0 & 0x00ffffff)
66        } else {
67            self.0.fmt(f)
68        }
69    }
70}
71
72/// A list of versions in arbitrary order.
73#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
74pub struct Versions(pub Vec<Version>);
75
76impl Decode for Versions {
77    /// Decode the version list.
78    fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
79        let count = usize::decode(r)?;
80        let mut vs = Vec::new();
81
82        for _ in 0..count {
83            let v = Version::decode(r)?;
84            vs.push(v);
85        }
86
87        Ok(Self(vs))
88    }
89}
90
91impl Encode for Versions {
92    /// Encode the version list.
93    fn encode<W: bytes::BufMut>(&self, w: &mut W) -> Result<(), EncodeError> {
94        self.0.len().encode(w)?;
95
96        for v in &self.0 {
97            v.encode(w)?;
98        }
99
100        Ok(())
101    }
102}
103
104impl Deref for Versions {
105    type Target = Vec<Version>;
106
107    fn deref(&self) -> &Self::Target {
108        &self.0
109    }
110}
111
112impl From<Vec<Version>> for Versions {
113    fn from(vs: Vec<Version>) -> Self {
114        Self(vs)
115    }
116}
117
118impl<const N: usize> From<[Version; N]> for Versions {
119    fn from(vs: [Version; N]) -> Self {
120        Self(vs.to_vec())
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127    use bytes::BytesMut;
128
129    #[test]
130    fn encode_decode() {
131        let mut buf = BytesMut::new();
132        let versions = Versions(vec![Version(1), Version::DRAFT_12, Version::DRAFT_13]);
133
134        versions.encode(&mut buf).unwrap();
135        #[rustfmt::skip]
136        assert_eq!(
137            buf.to_vec(),
138            vec![
139                0x03, // 3 Versions
140                // Version 1
141                0x01,
142                // Version DRAFT_12 (0xff00000c)
143                0xC0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0C,
144                // Version DRAFT_13 (0xff00000d)
145                0xC0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0D,
146            ]
147        );
148
149        let decoded = Versions::decode(&mut buf).unwrap();
150        assert_eq!(decoded, versions);
151    }
152}