use crate::resp::{ArgLayout, ArgSerializer};
use bytes::{Bytes, BytesMut};
use serde::{Serialize, ser::SerializeSeq};
use smallvec::SmallVec;
pub struct CommandArgsMut {
pub(crate) buffer: BytesMut,
pub(crate) args_layout: SmallVec<[ArgLayout; 10]>,
}
impl Default for CommandArgsMut {
fn default() -> Self {
Self {
buffer: BytesMut::with_capacity(1024),
args_layout: Default::default(),
}
}
}
impl CommandArgsMut {
#[inline(always)]
pub fn arg(mut self, arg: impl Serialize) -> Self {
let mut serializer = ArgSerializer::new(&mut self.buffer, &mut self.args_layout);
arg.serialize(&mut serializer)
.expect("Arg serialization failed");
self
}
#[inline]
pub fn len(&self) -> usize {
self.args_layout.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.args_layout.is_empty()
}
#[inline]
pub fn freeze(self) -> CommandArgs {
CommandArgs {
buffer: self.buffer.freeze(),
args_layout: self.args_layout,
}
}
}
impl Serialize for CommandArgsMut {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
struct RawBytes<'a>(&'a [u8]);
impl<'a> Serialize for RawBytes<'a> {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(self.0)
}
}
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for arg_layout in &self.args_layout {
let arg_bytes = &self.buffer[arg_layout.range()];
seq.serialize_element(&RawBytes(arg_bytes))?;
}
seq.end()
}
}
#[derive(Default)]
pub struct CommandArgs {
pub(crate) buffer: Bytes,
pub(crate) args_layout: SmallVec<[ArgLayout; 10]>,
}
impl CommandArgs {
#[inline]
pub fn len(&self) -> usize {
self.args_layout.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.args_layout.is_empty()
}
pub fn iter(&self) -> CommandArgsIterator<'_> {
self.into_iter()
}
}
impl Serialize for CommandArgs {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for arg in self {
seq.serialize_element(&arg)?;
}
seq.end()
}
}
impl<'a> IntoIterator for &'a CommandArgs {
type Item = Bytes;
type IntoIter = CommandArgsIterator<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
CommandArgsIterator {
buffer: self.buffer.clone(),
layout_iter: self.args_layout.iter(),
}
}
}
pub struct CommandArgsIterator<'a> {
pub(crate) buffer: Bytes,
pub(crate) layout_iter: std::slice::Iter<'a, ArgLayout>,
}
impl<'a> Iterator for CommandArgsIterator<'a> {
type Item = Bytes;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let arg_layout = self.layout_iter.next()?;
Some(self.buffer.slice(arg_layout.range()))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.layout_iter.size_hint()
}
}
impl<'a> DoubleEndedIterator for CommandArgsIterator<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
let arg_layout = self.layout_iter.next_back()?;
Some(self.buffer.slice(arg_layout.range()))
}
}
impl<'a> ExactSizeIterator for CommandArgsIterator<'a> {
fn len(&self) -> usize {
self.layout_iter.len()
}
}