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