redis-on-mysql 0.0.1

A Redis-compatible proxy that stores all data and Pub/Sub state in MySQL
Documentation
use resp_async::response::RespError;
use resp_async::{ClientId, Cmd, Value};

use crate::handlers::util::{arg_as_bytes, arg_as_i64, ok, wrong_arity};
use crate::state::SessionHandle;

pub async fn echo(
    Cmd(cmd): Cmd,
    SessionHandle(session): SessionHandle,
) -> Result<Value, RespError> {
    if cmd.args.len() != 1 {
        return Err(wrong_arity("ECHO"));
    }
    let _auth = session.auth().await.ok_or(RespError::NoAuth)?;
    let payload = arg_as_bytes(&cmd.args[0])?;
    Ok(Value::Bulk(payload.clone()))
}

pub async fn select(
    Cmd(cmd): Cmd,
    SessionHandle(session): SessionHandle,
) -> Result<Value, RespError> {
    if cmd.args.len() != 1 {
        return Err(wrong_arity("SELECT"));
    }
    let _auth = session.auth().await.ok_or(RespError::NoAuth)?;
    let index = arg_as_i64(&cmd.args[0])?;
    if index != 0 {
        return Err(RespError::invalid_data("ERR DB index is out of range"));
    }
    Ok(ok())
}

pub async fn client(
    Cmd(cmd): Cmd,
    ClientId(client_id): ClientId,
    SessionHandle(session): SessionHandle,
) -> Result<Value, RespError> {
    if cmd.args.is_empty() {
        return Err(wrong_arity("CLIENT"));
    }
    let _auth = session.auth().await.ok_or(RespError::NoAuth)?;
    let mut sub = arg_as_bytes(&cmd.args[0])?.to_vec();
    for b in &mut sub {
        b.make_ascii_uppercase();
    }
    match sub.as_slice() {
        b"ID" => {
            if cmd.args.len() != 1 {
                return Err(wrong_arity("CLIENT"));
            }
            Ok(Value::Integer(client_id as i64))
        }
        b"SETNAME" => {
            if cmd.args.len() != 2 {
                return Err(wrong_arity("CLIENT"));
            }
            let name = arg_as_bytes(&cmd.args[1])?;
            session.set_client_name(Some(name.clone())).await;
            Ok(ok())
        }
        b"GETNAME" => {
            if cmd.args.len() != 1 {
                return Err(wrong_arity("CLIENT"));
            }
            Ok(session
                .client_name()
                .await
                .map(Value::Bulk)
                .unwrap_or(Value::Null))
        }
        _ => Err(RespError::invalid_data("ERR command not supported")),
    }
}