rustis 0.7.2

Redis async driver for Rust
Documentation
use crate::{
    resp::{CommandArg, Command, CommandArgs},
    Error, Result,
};
use bytes::{BufMut, BytesMut};
use tokio_util::codec::Encoder;

pub(crate) struct CommandEncoder;

impl Encoder<&Command> for CommandEncoder {
    type Error = Error;

    fn encode(&mut self, command: &Command, buf: &mut BytesMut) -> Result<()> {
        buf.put_u8(b'*');
        encode_integer(command.args.len() as i64 + 1, buf);
        encode_crlf(buf);
    
        encode_bulkstring(&CommandArg::Str(command.name), buf);
        encode_command_args(&command.args, buf);

        Ok(())
    }
}

fn encode_bulkstring(bulk_string: &CommandArg, buf: &mut BytesMut) {
    match bulk_string {
        CommandArg::Nil => buf.put(&b"$-1\r\n"[..]),
        CommandArg::Signed(i) => {
            let mut temp = itoa::Buffer::new();
            let str = temp.format(*i);

            buf.put_u8(b'$');
            encode_integer(str.len() as i64, buf);
            encode_crlf(buf);
            buf.put(str.as_bytes());
            encode_crlf(buf);
        }
        CommandArg::Unsigned(u) => {
            let mut temp = itoa::Buffer::new();
            let str = temp.format(*u);

            buf.put_u8(b'$');
            encode_integer(str.len() as i64, buf);
            encode_crlf(buf);
            buf.put(str.as_bytes());
            encode_crlf(buf);
        }
        CommandArg::F32(f) => {
            let mut temp = dtoa::Buffer::new();
            let str = temp.format(*f);

            buf.put_u8(b'$');
            encode_integer(str.len() as i64, buf);
            encode_crlf(buf);
            buf.put(str.as_bytes());
            encode_crlf(buf);
        }
        CommandArg::F64(f) => {
            let mut temp = dtoa::Buffer::new();
            let str = temp.format(*f);

            buf.put_u8(b'$');
            encode_integer(str.len() as i64, buf);
            encode_crlf(buf);
            buf.put(str.as_bytes());
            encode_crlf(buf);
        }
        _ => {
            buf.put_u8(b'$');
            encode_integer(bulk_string.len() as i64, buf);
            encode_crlf(buf);
            buf.put(bulk_string.as_bytes());
            encode_crlf(buf);
        }
    }
}

fn encode_command_args(command_args: &CommandArgs, buf: &mut BytesMut) {
    match command_args {
        CommandArgs::Empty => (),
        CommandArgs::Single(arg) => {
            encode_bulkstring(arg, buf);
        }
        CommandArgs::Array2(args) => {
            for arg in args.iter() {
                encode_bulkstring(arg, buf);
            }
        }
        CommandArgs::Array3(args) => {
            for arg in args.iter() {
                encode_bulkstring(arg, buf);
            }
        }
        CommandArgs::Array4(args) => {
            for arg in args.iter() {
                encode_bulkstring(arg, buf);
            }
        }
        CommandArgs::Array5(args) => {
            for arg in args.iter() {
                encode_bulkstring(arg, buf);
            }
        }
        CommandArgs::Vec(args) => {
            for arg in args.iter() {
                encode_bulkstring(arg, buf);
            }
        }
    }
}

fn encode_integer(i: i64, buf: &mut BytesMut) {
    let mut buffer = itoa::Buffer::new();
    let str = buffer.format(i);
    buf.put(str.as_bytes());
}

fn encode_crlf(buf: &mut BytesMut) {
    buf.put(&b"\r\n"[..]);
}