nex_packet/
flowcontrol.rs1use core::fmt;
3
4use bytes::{Buf, BufMut, Bytes};
5use nex_core::bitfield::u16be;
6
7use crate::packet::{GenericMutablePacket, Packet};
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[repr(u16)]
14pub enum FlowControlOpcode {
15 Pause = 0x0001,
16 Unknown(u16),
17}
18
19impl FlowControlOpcode {
20 pub fn new(value: u16) -> Self {
21 match value {
22 0x0001 => FlowControlOpcode::Pause,
23 other => FlowControlOpcode::Unknown(other),
24 }
25 }
26
27 pub fn value(&self) -> u16 {
28 match *self {
29 FlowControlOpcode::Pause => 0x0001,
30 FlowControlOpcode::Unknown(v) => v,
31 }
32 }
33}
34
35impl fmt::Display for FlowControlOpcode {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 write!(
38 f,
39 "{}",
40 match self {
41 FlowControlOpcode::Pause => "pause",
42 FlowControlOpcode::Unknown(_) => "unknown",
43 }
44 )
45 }
46}
47
48pub struct FlowControlPacket {
52 pub command: FlowControlOpcode,
53 pub quanta: u16be,
54 pub payload: Bytes,
55}
56
57impl Packet for FlowControlPacket {
58 type Header = ();
59 fn from_buf(mut bytes: &[u8]) -> Option<Self> {
60 if bytes.len() < 4 {
61 return None;
62 }
63
64 let command = FlowControlOpcode::new(bytes.get_u16());
65 let quanta = bytes.get_u16();
66
67 let payload = Bytes::copy_from_slice(bytes);
69
70 Some(Self {
71 command,
72 quanta: quanta.into(),
73 payload,
74 })
75 }
76
77 fn from_bytes(bytes: Bytes) -> Option<Self> {
78 Self::from_buf(&bytes)
79 }
80
81 fn to_bytes(&self) -> Bytes {
82 let mut buf = bytes::BytesMut::with_capacity(4 + self.payload.len());
83
84 buf.put_u16(self.command.value());
85 buf.put_u16(self.quanta.into());
86 buf.put_slice(&self.payload);
87
88 buf.freeze()
89 }
90 fn header(&self) -> Bytes {
91 let mut buf = bytes::BytesMut::with_capacity(4);
92
93 buf.put_u16(self.command.value());
94 buf.put_u16(self.quanta.into());
95
96 buf.freeze()
97 }
98
99 fn payload(&self) -> Bytes {
100 self.payload.clone()
101 }
102
103 fn header_len(&self) -> usize {
104 4
105 }
106
107 fn payload_len(&self) -> usize {
108 self.payload.len()
109 }
110
111 fn total_len(&self) -> usize {
112 self.header_len() + self.payload_len()
113 }
114
115 fn into_parts(self) -> (Self::Header, Bytes) {
116 ((), self.to_bytes())
117 }
118}
119
120pub type MutableFlowControlPacket<'a> = GenericMutablePacket<'a, FlowControlPacket>;
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126 use crate::packet::MutablePacket;
127
128 #[test]
129 fn flowcontrol_pause_test() {
130 let packet = Bytes::from_static(&[
131 0x00, 0x01, 0x12, 0x34, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, ]);
135
136 let fc_packet = FlowControlPacket::from_bytes(packet.clone()).unwrap();
137 assert_eq!(fc_packet.command, FlowControlOpcode::Pause);
138 assert_eq!(fc_packet.quanta, 0x1234);
139 assert_eq!(fc_packet.to_bytes(), packet);
140 }
141
142 #[test]
143 fn flowcontrol_mutable_packet() {
144 let mut raw = [
145 0x00, 0x01, 0x12, 0x34, 0xaa, 0xbb,
148 ];
149
150 let mut packet = <MutableFlowControlPacket as MutablePacket>::new(&mut raw)
151 .expect("mutable flowcontrol");
152 packet.header_mut()[0] = 0x00;
153 packet.header_mut()[1] = 0x02;
154 packet.payload_mut()[0] = 0xff;
155
156 let frozen = packet.freeze().expect("freeze");
157 assert_eq!(frozen.command, FlowControlOpcode::Unknown(2));
158 assert_eq!(frozen.payload[0], 0xff);
159 }
160}