stun_rs/attributes/turn/
even_port.rs1use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
2use crate::common::check_buffer_boundaries;
3use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
4use crate::StunError;
5
6const EVEN_PORT: u16 = 0x0018;
7const EVEN_PORT_SIZE: usize = 1;
8
9#[derive(Debug, Clone, Default, PartialEq, Eq)]
26pub struct EvenPort(bool);
27
28impl EvenPort {
29 pub fn new(reserve: bool) -> Self {
35 Self(reserve)
36 }
37
38 pub fn reserve(&self) -> bool {
41 self.0
42 }
43}
44
45impl From<bool> for EvenPort {
46 fn from(value: bool) -> Self {
47 EvenPort::new(value)
48 }
49}
50
51impl DecodeAttributeValue for EvenPort {
52 fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
53 let raw_value = ctx.raw_value();
54 check_buffer_boundaries(raw_value, EVEN_PORT_SIZE)?;
55 Ok((Self(raw_value[0] & 0x80 == 0x80), EVEN_PORT_SIZE))
56 }
57}
58
59impl EncodeAttributeValue for EvenPort {
60 fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
61 let raw_value = ctx.raw_value_mut();
62 check_buffer_boundaries(raw_value, EVEN_PORT_SIZE)?;
63 raw_value[0] = if self.0 { 0x80 } else { 0x00 };
64 Ok(EVEN_PORT_SIZE)
65 }
66}
67
68impl crate::attributes::AsVerifiable for EvenPort {}
69
70stunt_attribute!(EvenPort, EVEN_PORT);
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::error::StunErrorType;
75 use crate::StunAttribute;
76
77 #[test]
78 fn even_port_constructor() {
79 let attr = EvenPort::new(true);
80 assert!(attr.reserve());
81
82 let attr = EvenPort::new(false);
83 assert!(!attr.reserve());
84
85 let attr = EvenPort::default();
86 assert!(!attr.reserve());
87
88 let attr = EvenPort::from(true);
89 assert!(attr.reserve());
90
91 let attr = EvenPort::from(false);
92 assert!(!attr.reserve());
93 }
94
95 #[test]
96 fn decode_even_port_value() {
97 let dummy_msg = [];
98 let buffer = [];
99 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
100 let result = EvenPort::decode(ctx);
101 assert_eq!(
102 result.expect_err("Error expected"),
103 StunErrorType::SmallBuffer
104 );
105
106 let buffer = [0x00];
107 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
108 let (attr, size) = EvenPort::decode(ctx).expect("Can not decode EvenPort");
109 assert_eq!(size, 1);
110 assert!(!attr.reserve());
111
112 let buffer = [0x80];
113 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
114 let (attr, size) = EvenPort::decode(ctx).expect("Can not decode EvenPort");
115 assert_eq!(size, 1);
116 assert!(attr.reserve());
117 }
118
119 #[test]
120 fn encode_even_port_value() {
121 let attr = EvenPort::new(true);
122 let dummy_msg = [];
123
124 let mut buffer = [];
125 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
126 let result = attr.encode(ctx);
127 assert_eq!(
128 result.expect_err("Error expected"),
129 StunErrorType::SmallBuffer
130 );
131
132 let mut buffer = [0xFF];
133 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
134 let result = attr.encode(ctx);
135 assert_eq!(result, Ok(1));
136 let expected_buffer = [0x80];
137 assert_eq!(&buffer[..], &expected_buffer[..]);
138
139 let attr = EvenPort::default();
140 let mut buffer = [0xFF];
141 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
142 let result = attr.encode(ctx);
143 assert_eq!(result, Ok(1));
144 let expected_buffer = [0x00];
145 assert_eq!(&buffer[..], &expected_buffer[..]);
146 }
147
148 #[test]
149 fn even_port_stunt_attribute() {
150 let attr = StunAttribute::EvenPort(EvenPort::new(true));
151 assert!(attr.is_even_port());
152 assert!(attr.as_even_port().is_ok());
153 assert!(attr.as_error_code().is_err());
154
155 assert!(attr.attribute_type().is_comprehension_required());
156 assert!(!attr.attribute_type().is_comprehension_optional());
157
158 let dbg_fmt = format!("{:?}", attr);
159 assert_eq!("EvenPort(EvenPort(true))", dbg_fmt);
160 }
161}