From cfe3bb0d5cc843707a706ab68e0ad30d6c59863c Mon Sep 17 00:00:00 2001 From: Alex van de Sandt Date: Thu, 7 May 2026 09:48:31 -0500 Subject: [PATCH] Write docs for command/response/param traits --- src/codec.rs | 2 +- src/command/macros.rs | 2 +- src/command/mod.rs | 36 ++++++++++++++++++++++++++++++++++-- src/command/no_params.rs | 2 +- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index 1c31a8c..514ab4a 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -32,7 +32,7 @@ where fn encode(&mut self, item: Cmd, dst: &mut BytesMut) -> Result<(), Self::Error> { let params = item.params(); - let est_len = Cmd::TEXT.len() + params.count() + params.total_size() + 1; + let est_len = Cmd::TEXT.len() + params.count() + params.max_size() + 1; dst.reserve(est_len); dst.extend_from_slice(Cmd::TEXT); diff --git a/src/command/macros.rs b/src/command/macros.rs index 88183b6..312ed9c 100644 --- a/src/command/macros.rs +++ b/src/command/macros.rs @@ -67,7 +67,7 @@ macro_rules! range_param { fn count(&self) -> usize { 1 } - fn total_size(&self) -> usize { + fn max_size(&self) -> usize { <$type as ::itoa::Integer>::MAX_STR_LEN } fn serialize_to(&self, mut buffer: crate::command::ParamBuffer) { diff --git a/src/command/mod.rs b/src/command/mod.rs index ac2e44b..b5d06bf 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -6,34 +6,65 @@ mod ok_response; use tokio_util::bytes::{BufMut, Bytes, BytesMut}; +pub use ok_response::{OkResponse, OkResponseError}; + pub(crate) use macros::{command, range_param, range_response}; pub(crate) use no_params::NoParams; -pub use ok_response::{OkResponse, OkResponseError}; use crate::codec::PARAM_DELIMITER; +/// Defines a command that can be sent to a scanner, including params and the response type. pub trait Command { + /// The three-character text of the command itself (for example: `VOL`, `EPG`) const TEXT: &'static [u8]; + + /// The type of the parameters sent with this command type Params: Params; + /// The values this command expects from the scanner in response type Response: Response; fn params(&self) -> &Self::Params; } +/// Tells the codec how to parse a response to a command pub trait Response: Sized { + /// The type returned when parsing fails type Error: std::error::Error; + /// Given a list of raw values, parses the response into a concrete type. + /// + /// The length of `raw_values` will always be equal to [`Response::expected_field_count`] fn deserialize(raw_values: &[Bytes]) -> Result; + /// The number of values expected by this command, not including the command itself. fn expected_field_count() -> usize; } pub trait Params { + /// How many parameters are included in this command + /// + /// This is used to determine how much space to reserve for `,` delimiters in the command + /// buffer before serialization. fn count(&self) -> usize; - fn total_size(&self) -> usize; + + /// The maximum number of bytes these parameters could take up, not including their `,` + /// delimiters + /// + /// * For numeric values, this is usually the maximum number of digits in their decimal representation + /// * For string values, this is their max length + /// + /// This is used to determine how much space to reserve for the parameters in the command buffer + /// before serialization. + fn max_size(&self) -> usize; + + /// Serialize the parameters into a given buffer + /// + /// Implementors should sequentially call [`ParamBuffer::serialize_param`] with each parameter. The + /// buffer will handle any delimiters. fn serialize_to(&self, buffer: ParamBuffer); } +/// Thin wrapper around [`BytesMut`] for parameter serialization pub struct ParamBuffer<'a>(&'a mut BytesMut); impl<'a> ParamBuffer<'a> { @@ -41,6 +72,7 @@ impl<'a> ParamBuffer<'a> { Self(bytes) } + /// Add a `,` delimiter before pushing the given bytes to the buffer pub fn serialize_param(&mut self, bytes: &[u8]) { self.0.put_u8(PARAM_DELIMITER); self.0.extend_from_slice(bytes); diff --git a/src/command/no_params.rs b/src/command/no_params.rs index b74ddf5..19e5391 100644 --- a/src/command/no_params.rs +++ b/src/command/no_params.rs @@ -7,7 +7,7 @@ impl Params for NoParams { 0 } - fn total_size(&self) -> usize { + fn max_size(&self) -> usize { 0 } -- 2.51.2