use crate::coding::{Decode, DecodeError, Encode, EncodeError, KeyValuePairs};
use bytes::Buf as _;
#[derive(Debug)]
pub struct Server {
pub params: KeyValuePairs,
}
impl Decode for Server {
fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
let typ = u64::decode(r)?;
if typ != 0x21 {
return Err(DecodeError::InvalidMessage(typ));
}
let len = u16::decode(r)? as usize;
<u64 as Decode>::decode_remaining(r, len)?;
let mut payload = r.copy_to_bytes(len);
let params = KeyValuePairs::decode(&mut payload)?;
if payload.has_remaining() {
return Err(DecodeError::InvalidMessage(typ));
}
Ok(Self { params })
}
}
impl Encode for Server {
fn encode<W: bytes::BufMut>(&self, w: &mut W) -> Result<(), EncodeError> {
(0x21_u64).encode(w)?;
let mut buf = Vec::new();
self.params.encode(&mut buf)?;
if buf.len() > u16::MAX as usize {
return Err(EncodeError::MsgBoundsExceeded);
}
(buf.len() as u16).encode(w)?;
Self::encode_remaining(w, buf.len())?;
w.put_slice(&buf);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::setup::ParameterType;
use bytes::BytesMut;
#[test]
fn encode_decode_params_only() {
let mut buf = BytesMut::new();
let mut params = KeyValuePairs::default();
params.set_intvalue(ParameterType::MaxRequestId.into(), 1000);
let server = Server { params };
server.encode(&mut buf).unwrap();
let bytes = buf.to_vec();
assert_eq!(bytes[0], 0x21);
let payload_len = u16::from_be_bytes([bytes[1], bytes[2]]) as usize;
assert_eq!(bytes.len(), 3 + payload_len);
let decoded = Server::decode(&mut buf).unwrap();
assert_eq!(decoded.params, server.params);
}
#[test]
fn encode_decode_no_params() {
let mut buf = BytesMut::new();
let server = Server {
params: KeyValuePairs::default(),
};
server.encode(&mut buf).unwrap();
assert_eq!(buf[0], 0x21);
let payload_len = u16::from_be_bytes([buf[1], buf[2]]) as usize;
assert_eq!(payload_len, 1);
let decoded = Server::decode(&mut buf).unwrap();
assert!(decoded.params.0.is_empty());
}
#[test]
fn decode_rejects_overlong_payload() {
let mut buf = BytesMut::new();
let server = Server {
params: KeyValuePairs::default(),
};
server.encode(&mut buf).unwrap();
buf[2] += 1;
buf.extend_from_slice(&[0x00]);
assert!(matches!(
Server::decode(&mut buf).unwrap_err(),
DecodeError::InvalidMessage(0x21)
));
}
}