turn_types/attribute/
transport.rs1use stun_types::{attribute::*, message::StunParseError};
10
11#[derive(Debug, Clone)]
17pub struct RequestedTransport {
18 protocol: u8,
19}
20
21impl AttributeStaticType for RequestedTransport {
22 const TYPE: AttributeType = AttributeType::new(0x0019);
23}
24
25impl Attribute for RequestedTransport {
26 fn get_type(&self) -> AttributeType {
27 Self::TYPE
28 }
29
30 fn length(&self) -> u16 {
31 4
32 }
33}
34
35impl AttributeWrite for RequestedTransport {
36 fn to_raw(&self) -> RawAttribute<'_> {
37 RawAttribute::new(self.get_type(), &[self.protocol, 0, 0, 0]).into_owned()
38 }
39
40 fn write_into_unchecked(&self, dest: &mut [u8]) {
41 self.write_header_unchecked(dest);
42 dest[4] = self.protocol;
43 dest[5] = 0x0;
44 dest[6] = 0x0;
45 dest[7] = 0x0;
46 }
47}
48
49impl AttributeFromRaw<'_> for RequestedTransport {
50 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
51 where
52 Self: Sized,
53 {
54 Self::try_from(raw)
55 }
56}
57
58impl TryFrom<&RawAttribute<'_>> for RequestedTransport {
59 type Error = StunParseError;
60 fn try_from(raw: &RawAttribute) -> Result<Self, Self::Error> {
61 raw.check_type_and_len(Self::TYPE, 4..=4)?;
62 Ok(Self {
63 protocol: raw.value[0],
64 })
65 }
66}
67
68impl RequestedTransport {
69 pub const TCP: u8 = 6;
71 pub const UDP: u8 = 17;
73
74 pub fn new(protocol: u8) -> Self {
84 Self { protocol }
85 }
86
87 pub fn protocol(&self) -> u8 {
97 self.protocol
98 }
99}
100
101impl core::fmt::Display for RequestedTransport {
102 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
103 write!(f, "{}: {}", self.get_type(), self.protocol())
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110 use alloc::vec::Vec;
111 use byteorder::{BigEndian, ByteOrder};
112 use std::println;
113
114 #[test]
115 fn requested_transport() {
116 let _log = crate::tests::test_init_log();
117 let trans = RequestedTransport::new(17);
118 assert_eq!(trans.get_type(), RequestedTransport::TYPE);
119 assert_eq!(trans.protocol(), 17);
120 let raw: RawAttribute = trans.to_raw();
121 println!("raw: {raw:?}");
122 assert_eq!(raw.get_type(), RequestedTransport::TYPE);
123 let trans2 = RequestedTransport::try_from(&raw).unwrap();
124 assert_eq!(trans2.get_type(), RequestedTransport::TYPE);
125 assert_eq!(trans2.protocol(), 17);
126 let mut data: Vec<_> = raw.into();
128 BigEndian::write_u16(&mut data[0..2], 0);
129 assert!(matches!(
130 RequestedTransport::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
131 Err(StunParseError::WrongAttributeImplementation)
132 ));
133 let mut data = [0; 8];
134 trans.write_into(&mut data).unwrap();
135 let raw = RawAttribute::from_bytes(&data).unwrap();
136 let trans2 = RequestedTransport::from_raw_ref(&raw).unwrap();
137 assert_eq!(trans.protocol(), trans2.protocol());
138 }
139}