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