pn_dcp/
block.rs

1use crate::comm::BytesWrap;
2use crate::options::IpBlockInfo;
3use crate::options::{
4    BlockError, BlockInfo, BlockQualifier, InnerIpAddr, OptionAndSub, OptionAndSubValue,
5};
6use anyhow::{bail, Result};
7
8pub trait BlockTrait {
9    fn len(&self) -> usize;
10    fn payload(&self) -> u16;
11    fn append_data(&self, data: &mut Vec<u8>);
12}
13#[derive(Debug, Eq, PartialEq, Clone)]
14pub struct BlockPadding;
15
16impl BlockTrait for BlockPadding {
17    fn len(&self) -> usize {
18        1
19    }
20
21    fn payload(&self) -> u16 {
22        0
23    }
24
25    fn append_data(&self, data: &mut Vec<u8>) {
26        data.push(0u8);
27    }
28}
29#[derive(Debug, Eq, PartialEq, Clone)]
30pub struct BlockOptionAndSub(pub(crate) OptionAndSub);
31
32impl From<OptionAndSub> for BlockOptionAndSub {
33    fn from(a: OptionAndSub) -> Self {
34        Self(a)
35    }
36}
37impl BlockTrait for BlockOptionAndSub {
38    fn len(&self) -> usize {
39        2
40    }
41
42    fn payload(&self) -> u16 {
43        0
44    }
45
46    fn append_data(&self, data: &mut Vec<u8>) {
47        let (a, b) = self.0.to_u8s();
48        data.push(a);
49        data.push(b);
50    }
51}
52
53#[derive(Debug, Eq, PartialEq, Clone)]
54pub struct BlockIp {
55    pub(crate) ip: InnerIpAddr,
56    pub(crate) info: IpBlockInfo,
57}
58impl BlockIp {
59    pub fn new(ip: InnerIpAddr, info: IpBlockInfo) -> Self {
60        Self { ip, info }
61    }
62    pub fn ip(&self) -> &InnerIpAddr {
63        &self.ip
64    }
65    pub fn info(&self) -> &IpBlockInfo {
66        &self.info
67    }
68    pub fn try_from_bytes(value: BytesWrap) -> Result<Self> {
69        let val = value.slice(2..)?;
70        let len = Len::try_from(val.as_ref())?;
71        let info = IpBlockInfo::try_from(value.slice(4..=5)?)?;
72        let ip = InnerIpAddr::new(value.slice(6..(len.0 + 4))?)?;
73        Ok(Self { ip, info })
74    }
75}
76impl BlockTrait for BlockIp {
77    fn len(&self) -> usize {
78        self.ip.payload_size() + 6
79    }
80
81    fn payload(&self) -> u16 {
82        14
83    }
84
85    fn append_data(&self, data: &mut Vec<u8>) {
86        data.extend_from_slice(OptionAndSub::IpAddr.to_u8_array().as_slice());
87        data.extend_from_slice(&14u16.to_be_bytes());
88        data.extend_from_slice(self.info.to_u8_array().as_slice());
89        self.ip.append_value_to_data(data);
90    }
91}
92
93#[derive(Debug, Eq, PartialEq, Clone)]
94pub struct BlockSet {
95    pub(crate) option: OptionAndSubValue,
96    pub(crate) qualifier: BlockQualifier,
97}
98
99impl BlockSet {
100    pub fn new(option: OptionAndSubValue, qualifier: BlockQualifier) -> Self {
101        Self { option, qualifier }
102    }
103    pub fn option(&self) -> &OptionAndSubValue {
104        &self.option
105    }
106    pub fn qualifier(&self) -> &BlockQualifier {
107        &self.qualifier
108    }
109}
110
111impl TryFrom<BytesWrap> for BlockSet {
112    type Error = anyhow::Error;
113    fn try_from(value: BytesWrap) -> Result<Self, Self::Error> {
114        let ty = OptionAndSub::try_from(value.clone())?;
115        let val = value.slice(2..)?;
116        let len = Len::try_from(val.as_ref())?;
117        let qualifier = BlockQualifier::try_from(value.slice(4..=5)?)?;
118        let val = value.slice(6..(len.0 + 4))?;
119        let option = OptionAndSubValue::init_by_ty(ty, val)?;
120        Ok(Self { option, qualifier })
121    }
122}
123
124impl BlockTrait for BlockSet {
125    fn len(&self) -> usize {
126        self.option.payload_size() + 6
127    }
128
129    fn payload(&self) -> u16 {
130        (self.option.payload_size() + 2) as u16
131    }
132
133    fn append_data(&self, data: &mut Vec<u8>) {
134        self.option.append_option_to_data(data);
135        data.extend_from_slice(self.payload().to_be_bytes().as_slice());
136        data.extend_from_slice(self.qualifier.to_u8_array().as_slice());
137        self.option.append_value_to_data(data);
138    }
139}
140
141#[derive(Debug, Eq, PartialEq, Clone)]
142pub struct BlockCommon {
143    pub(crate) option: OptionAndSubValue,
144    pub(crate) info: BlockInfo,
145}
146
147impl BlockCommon {
148    pub fn option(&self) -> &OptionAndSubValue {
149        &self.option
150    }
151    pub fn info(&self) -> &BlockInfo {
152        &self.info
153    }
154    pub fn new(option: OptionAndSubValue) -> Self {
155        Self {
156            option,
157            info: BlockInfo::Reserved,
158        }
159    }
160    pub fn set_block_info(&mut self, info: BlockInfo) {
161        self.info = info;
162    }
163    pub fn try_from_bytes(ty: OptionAndSub, value: BytesWrap) -> Result<Self> {
164        let val = value.slice(2..)?;
165        let len = Len::try_from(val.as_ref())?;
166        let info = BlockInfo::try_from(value.slice(4..=5)?)?;
167        let val = value.slice(6..(len.0 + 4))?;
168        let option = OptionAndSubValue::init_by_ty(ty, val)?;
169        Ok(Self { option, info })
170    }
171}
172impl BlockTrait for BlockCommon {
173    fn len(&self) -> usize {
174        self.option.payload_size() + 6
175    }
176
177    fn payload(&self) -> u16 {
178        (self.option.payload_size() + 2) as u16
179    }
180
181    fn append_data(&self, data: &mut Vec<u8>) {
182        self.option.append_option_to_data(data);
183        data.extend_from_slice(
184            ((self.option.payload_size() + 2) as u16)
185                .to_be_bytes()
186                .as_slice(),
187        );
188        data.extend_from_slice(self.info.to_u8_array().as_slice());
189        self.option.append_value_to_data(data);
190    }
191}
192#[derive(Debug, Eq, PartialEq, Clone)]
193pub struct BlockResp(pub OptionAndSub, pub BlockError);
194impl BlockTrait for BlockResp {
195    fn len(&self) -> usize {
196        7
197    }
198
199    fn payload(&self) -> u16 {
200        3
201    }
202
203    fn append_data(&self, data: &mut Vec<u8>) {
204        data.extend_from_slice(OptionAndSub::Response.to_u8_array().as_slice());
205        data.extend_from_slice(self.payload().to_be_bytes().as_slice());
206        data.extend_from_slice(self.0.to_u8_array().as_slice());
207        data.push(self.1 as u8);
208    }
209}
210
211impl TryFrom<BytesWrap> for BlockResp {
212    type Error = anyhow::Error;
213    fn try_from(value: BytesWrap) -> Result<Self, Self::Error> {
214        let ty = OptionAndSub::try_from(value.slice(4..=5)?)?;
215        let val = value.slice(6..=6)?.as_ref()[0];
216        Ok(Self(ty, BlockError::try_from(val)?))
217    }
218}
219
220#[derive(Debug, Eq, PartialEq, Clone)]
221pub struct BlockCommonWithoutInfo(pub(crate) OptionAndSubValue);
222
223impl From<OptionAndSubValue> for BlockCommonWithoutInfo {
224    fn from(a: OptionAndSubValue) -> Self {
225        Self(a)
226    }
227}
228
229impl TryFrom<BytesWrap> for BlockCommonWithoutInfo {
230    type Error = anyhow::Error;
231    fn try_from(value: BytesWrap) -> Result<Self, Self::Error> {
232        let ty = OptionAndSub::try_from(value.clone())?;
233        let val = value.slice(2..)?;
234        let len = Len::try_from(val.as_ref())?;
235        let val = value.slice(4..(len.0 + 4))?;
236        Ok(Self(OptionAndSubValue::init_by_ty(ty, val)?))
237    }
238}
239
240impl BlockTrait for BlockCommonWithoutInfo {
241    fn len(&self) -> usize {
242        self.0.payload_size() + 4
243    }
244
245    fn payload(&self) -> u16 {
246        self.0.payload_size() as u16
247    }
248
249    fn append_data(&self, data: &mut Vec<u8>) {
250        self.0.append_option_to_data(data);
251        data.extend_from_slice((self.0.payload_size() as u16).to_be_bytes().as_slice());
252        self.0.append_value_to_data(data);
253    }
254}
255
256pub struct Len(pub usize);
257impl TryFrom<&[u8]> for Len {
258    type Error = anyhow::Error;
259    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
260        if let Some(val) = value.get(0..=1) {
261            let len = u16::from_be_bytes([val[0], val[1]]) as usize;
262            Ok(Len(len))
263        } else {
264            bail!("")
265        }
266    }
267}