use crate::proto::error::ProtoError;
use bytes::{Buf, BufMut, Bytes, BytesMut};
#[derive(Debug, Clone)]
pub struct SzlRequest {
pub szl_id: u16,
pub szl_index: u16,
}
#[derive(Debug, Clone)]
pub struct SzlResponse {
pub szl_id: u16,
pub szl_index: u16,
pub data: Bytes,
}
impl SzlRequest {
pub fn encode(&self, buf: &mut BytesMut) {
buf.put_u8(0x00); buf.put_u8(0x01); buf.put_u8(0x12); buf.put_u8(0x04); buf.put_u8(0x11); buf.put_u8(0x44); buf.put_u8(0x01); buf.put_u8(0x00); buf.put_u16(self.szl_id);
buf.put_u16(self.szl_index);
}
pub fn decode(buf: &mut Bytes) -> Result<Self, ProtoError> {
if buf.len() < 12 {
return Err(ProtoError::BufferTooShort {
need: 12,
have: buf.len(),
});
}
buf.advance(8); let szl_id = buf.get_u16();
let szl_index = buf.get_u16();
Ok(SzlRequest { szl_id, szl_index })
}
}
impl SzlResponse {
pub fn decode(buf: &mut Bytes) -> Result<Self, ProtoError> {
if buf.len() < 12 {
return Err(ProtoError::BufferTooShort {
need: 12,
have: buf.len(),
});
}
buf.advance(8); let szl_id = buf.get_u16();
let szl_index = buf.get_u16();
let data = buf.split_to(buf.len());
Ok(SzlResponse {
szl_id,
szl_index,
data,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use bytes::{Bytes, BytesMut};
#[test]
fn szl_request_roundtrip() {
let req = SzlRequest {
szl_id: 0x0011,
szl_index: 0x0000,
};
let mut buf = BytesMut::new();
req.encode(&mut buf);
let mut b = buf.freeze();
let decoded = SzlRequest::decode(&mut b).unwrap();
assert_eq!(decoded.szl_id, 0x0011);
assert_eq!(decoded.szl_index, 0x0000);
}
#[test]
fn szl_request_encode_length() {
let req = SzlRequest {
szl_id: 0x0011,
szl_index: 0x0001,
};
let mut buf = BytesMut::new();
req.encode(&mut buf);
assert_eq!(buf.len(), 12);
}
#[test]
fn szl_response_decode_with_data() {
let mut raw = vec![0x00u8, 0x01, 0x12, 0x04, 0x11, 0x44, 0x01, 0x00];
raw.extend_from_slice(&[0x00, 0x11]); raw.extend_from_slice(&[0x00, 0x00]); raw.extend_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]); let mut b = Bytes::from(raw);
let resp = SzlResponse::decode(&mut b).unwrap();
assert_eq!(resp.szl_id, 0x0011);
assert_eq!(resp.szl_index, 0x0000);
assert_eq!(resp.data.as_ref(), &[0xDE, 0xAD, 0xBE, 0xEF]);
}
#[test]
fn szl_request_truncated_returns_err() {
let mut b = Bytes::from_static(b"\x00\x01\x12");
assert!(SzlRequest::decode(&mut b).is_err());
}
}