turn_types/attribute/
data.rs1use stun_types::{attribute::*, message::StunParseError};
10
11#[derive(Debug, Clone)]
17pub struct Data<'a> {
18 data: stun_types::data::Data<'a>,
19}
20
21impl AttributeStaticType for Data<'_> {
22 const TYPE: AttributeType = AttributeType::new(0x0013);
23}
24
25impl Attribute for Data<'_> {
26 fn get_type(&self) -> AttributeType {
27 Self::TYPE
28 }
29
30 fn length(&self) -> u16 {
31 self.data.len() as u16
32 }
33}
34
35impl AttributeWrite for Data<'_> {
36 fn to_raw(&self) -> RawAttribute<'_> {
37 RawAttribute::new(self.get_type(), &self.data)
38 }
39
40 fn write_into_unchecked(&self, dest: &mut [u8]) {
41 self.write_header_unchecked(dest);
42 dest[4..4 + self.data.len()].copy_from_slice(&self.data);
43 }
44}
45
46impl<'a> AttributeFromRaw<'a> for Data<'a> {
47 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
48 where
49 Self: Sized,
50 {
51 raw.check_type_and_len(Self::TYPE, ..)?;
52 Ok(Self {
53 data: raw.value.clone().into_owned(),
54 })
55 }
56
57 fn from_raw(raw: RawAttribute<'a>) -> Result<Self, StunParseError>
58 where
59 Self: Sized,
60 {
61 Self::try_from(raw)
62 }
63}
64
65impl<'a> TryFrom<RawAttribute<'a>> for Data<'a> {
66 type Error = StunParseError;
67
68 fn try_from(raw: RawAttribute<'a>) -> Result<Self, Self::Error> {
69 raw.check_type_and_len(Self::TYPE, ..)?;
70 Ok(Self { data: raw.value })
71 }
72}
73
74impl<'a> Data<'a> {
75 pub fn new(data: &'a [u8]) -> Self {
86 if data.len() > u16::MAX as usize {
87 panic!(
88 "Attempt made to create a Data attribute larger than {}",
89 u16::MAX
90 );
91 }
92 Self {
93 data: stun_types::data::Data::from(data),
94 }
95 }
96
97 pub fn data(&self) -> &[u8] {
108 &self.data
109 }
110}
111
112impl core::fmt::Display for Data<'_> {
113 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
114 write!(f, "{}: len:{}", self.get_type(), self.data.len())
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use alloc::vec;
122 use alloc::vec::Vec;
123 use byteorder::{BigEndian, ByteOrder};
124 use std::println;
125
126 #[test]
127 fn data() {
128 let _log = crate::tests::test_init_log();
129 let bytes = vec![0, 1, 2, 3, 4, 5];
130 let data = Data::new(&bytes);
131 assert_eq!(data.get_type(), Data::TYPE);
132 assert_eq!(data.data(), &bytes);
133 let raw: RawAttribute = data.to_raw();
134 println!("{}", raw);
135 assert_eq!(raw.get_type(), Data::TYPE);
136 let data2 = Data::try_from(raw.clone()).unwrap();
137 assert_eq!(data2.get_type(), Data::TYPE);
138 assert_eq!(data2.data(), &bytes);
139 let mut data: Vec<_> = raw.into();
141 BigEndian::write_u16(&mut data[0..2], 0);
142 assert!(matches!(
143 Data::try_from(RawAttribute::from_bytes(data.as_ref()).unwrap()),
144 Err(StunParseError::WrongAttributeImplementation)
145 ));
146 }
147}