turn_types/attribute/
fragment.rs1use stun_types::{attribute::*, message::StunParseError};
10
11#[derive(Default, Debug, Clone)]
17pub struct DontFragment {}
18impl AttributeStaticType for DontFragment {
19 const TYPE: AttributeType = AttributeType::new(0x001A);
20}
21
22impl Attribute for DontFragment {
23 fn get_type(&self) -> AttributeType {
24 Self::TYPE
25 }
26
27 fn length(&self) -> u16 {
28 0
29 }
30}
31
32impl AttributeWrite for DontFragment {
33 fn to_raw(&self) -> RawAttribute<'_> {
34 RawAttribute::new(self.get_type(), &[])
35 }
36 fn write_into_unchecked(&self, dest: &mut [u8]) {
37 self.write_header_unchecked(dest);
38 }
39}
40
41impl AttributeFromRaw<'_> for DontFragment {
42 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
43 where
44 Self: Sized,
45 {
46 Self::try_from(raw)
47 }
48}
49
50impl TryFrom<&RawAttribute<'_>> for DontFragment {
51 type Error = StunParseError;
52 fn try_from(raw: &RawAttribute) -> Result<Self, Self::Error> {
53 raw.check_type_and_len(Self::TYPE, 0..=0)?;
54 Ok(Self {})
55 }
56}
57
58impl DontFragment {
59 pub fn new() -> Self {
68 Self {}
69 }
70}
71
72impl std::fmt::Display for DontFragment {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 write!(f, "{}", self.get_type())
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use byteorder::{BigEndian, ByteOrder};
82
83 #[test]
84 fn dont_fragment() {
85 let _log = crate::tests::test_init_log();
86 let frag = DontFragment::new();
87 assert_eq!(frag.get_type(), DontFragment::TYPE);
88 let raw: RawAttribute = frag.to_raw();
89 println!("{}", raw);
90 assert_eq!(raw.get_type(), DontFragment::TYPE);
91 let frag2 = DontFragment::try_from(&raw).unwrap();
92 assert_eq!(frag2.get_type(), DontFragment::TYPE);
93 let mut data: Vec<_> = raw.into();
95 BigEndian::write_u16(&mut data[0..2], 0);
96 assert!(matches!(
97 DontFragment::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
98 Err(StunParseError::WrongAttributeImplementation)
99 ));
100 }
101}