use crate::WireError;
use crate::codec::{WireDecode, WireEncode, read_u8};
use bytes::{BufMut, BytesMut};
use std::borrow::Cow;
pub const OPTIONS_SCOPE_TOPIC: u8 = 1;
pub const OPTIONS_SCOPE_STREAM: u8 = 2;
pub const OPTIONS_SCOPE_USER: u8 = 3;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DescribeOptionsRequest {
pub scope: u8,
}
impl WireEncode for DescribeOptionsRequest {
fn encoded_size(&self) -> usize {
1
}
fn encode(&self, buf: &mut BytesMut) {
buf.put_u8(self.scope);
}
}
impl WireDecode for DescribeOptionsRequest {
fn decode(buf: &[u8]) -> Result<(Self, usize), WireError> {
let scope = read_u8(buf, 0)?;
if !(OPTIONS_SCOPE_TOPIC..=OPTIONS_SCOPE_USER).contains(&scope) {
return Err(WireError::Validation(Cow::Owned(format!(
"unknown options scope: {scope}"
))));
}
Ok((Self { scope }, 1))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn roundtrip() {
for scope in [
OPTIONS_SCOPE_TOPIC,
OPTIONS_SCOPE_STREAM,
OPTIONS_SCOPE_USER,
] {
let req = DescribeOptionsRequest { scope };
let bytes = req.to_bytes();
let (decoded, consumed) = DescribeOptionsRequest::decode(&bytes).unwrap();
assert_eq!(consumed, bytes.len());
assert_eq!(decoded, req);
}
}
#[test]
fn unknown_scope_rejected() {
assert!(DescribeOptionsRequest::decode(&[0]).is_err());
assert!(DescribeOptionsRequest::decode(&[4]).is_err());
}
#[test]
fn empty_buffer_rejected() {
assert!(DescribeOptionsRequest::decode(&[]).is_err());
}
}