turn_types/attribute/
fragment.rs1use stun_types::{attribute::*, message::StunParseError};
12
13#[derive(Default, Debug, Clone)]
19pub struct DontFragment {}
20impl AttributeStaticType for DontFragment {
21 const TYPE: AttributeType = AttributeType::new(0x001A);
22}
23
24impl Attribute for DontFragment {
25 fn get_type(&self) -> AttributeType {
26 Self::TYPE
27 }
28
29 fn length(&self) -> u16 {
30 0
31 }
32}
33
34impl AttributeWrite for DontFragment {
35 fn to_raw(&self) -> RawAttribute<'_> {
36 RawAttribute::new(self.get_type(), &[])
37 }
38 fn write_into_unchecked(&self, dest: &mut [u8]) {
39 self.write_header_unchecked(dest);
40 }
41}
42
43impl AttributeFromRaw<'_> for DontFragment {
44 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
45 where
46 Self: Sized,
47 {
48 Self::try_from(raw)
49 }
50}
51
52impl TryFrom<&RawAttribute<'_>> for DontFragment {
53 type Error = StunParseError;
54 fn try_from(raw: &RawAttribute) -> Result<Self, Self::Error> {
55 raw.check_type_and_len(Self::TYPE, 0..=0)?;
56 Ok(Self {})
57 }
58}
59
60impl DontFragment {
61 pub fn new() -> Self {
70 Self {}
71 }
72}
73
74impl core::fmt::Display for DontFragment {
75 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
76 write!(f, "{}", self.get_type())
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use alloc::{vec, vec::Vec};
84 use byteorder::{BigEndian, ByteOrder};
85 use tracing::trace;
86
87 #[test]
88 fn dont_fragment() {
89 let _log = crate::tests::test_init_log();
90 let frag = DontFragment::new();
91 assert_eq!(frag.get_type(), DontFragment::TYPE);
92 }
93
94 #[test]
95 fn dont_fragment_raw() {
96 let _log = crate::tests::test_init_log();
97 let frag = DontFragment::new();
98 let raw: RawAttribute = frag.to_raw();
99 trace!("{}", raw);
100 assert_eq!(raw.get_type(), DontFragment::TYPE);
101 let frag2 = DontFragment::try_from(&raw).unwrap();
102 assert_eq!(frag2.get_type(), DontFragment::TYPE);
103 }
104
105 #[test]
106 fn dont_fragment_raw_wrong_type() {
107 let _log = crate::tests::test_init_log();
108 let frag = DontFragment::new();
109 let raw: RawAttribute = frag.to_raw();
110 assert_eq!(raw.get_type(), DontFragment::TYPE);
111 let frag2 = DontFragment::try_from(&raw).unwrap();
112 assert_eq!(frag2.get_type(), DontFragment::TYPE);
113 let mut data: Vec<_> = raw.into();
115 BigEndian::write_u16(&mut data[0..2], 0);
116 assert!(matches!(
117 DontFragment::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
118 Err(StunParseError::WrongAttributeImplementation)
119 ));
120 }
121
122 #[test]
123 fn dont_fragment_write_into() {
124 let _log = crate::tests::test_init_log();
125 let frag = DontFragment::new();
126 let raw: RawAttribute = frag.to_raw();
127 let mut dest = vec![0; raw.padded_len()];
128 frag.write_into(&mut dest).unwrap();
129 let raw = RawAttribute::from_bytes(&dest).unwrap();
130 let frag2 = DontFragment::try_from(&raw).unwrap();
131 assert_eq!(frag2.get_type(), DontFragment::TYPE);
132 }
133
134 #[test]
135 #[should_panic = "out of range"]
136 fn dont_fragment_write_into_unchcked() {
137 let _log = crate::tests::test_init_log();
138 let frag = DontFragment::new();
139 let raw: RawAttribute = frag.to_raw();
140 let mut dest = vec![0; raw.padded_len() - 1];
141 frag.write_into_unchecked(&mut dest);
142 }
143}