redisx 0.0.2

Minimal and Asynchronous Redis client for Rust.
Documentation
use anyhow::bail;
use atoi::FromRadix10Checked;
use std::str;

// This is very much pre-alpha quality. This is only enough to do what I need at the moment.
// This module needs to be cleaned up, generalized, and made safe.

pub fn write_array_start(buf: &mut Vec<u8>, len: usize) {
    buf.push(b'*');

    buf.append(&mut len.to_string().into_bytes());

    write_terminator(buf);
}

pub fn write_terminator(buf: &mut Vec<u8>) {
    buf.push(b'\r');
    buf.push(b'\n');
}

pub fn write_len(buf: &mut Vec<u8>, val: usize) {
    buf.append(&mut val.to_string().into_bytes());

    write_terminator(buf);
}

pub fn write_str(buf: &mut Vec<u8>, s: &str) {
    buf.push(b'$');

    write_len(buf, s.len());

    buf.extend_from_slice(&s.as_bytes());

    write_terminator(buf);
}

pub fn read_str(buf: &[u8]) -> crate::Result<Option<String>> {
    if buf[0] != b'$' {
        bail!("expecting $ (STRING); found {}", buf[0] as char);
    }

    let (len, mut index) = usize::from_radix_10_checked(&buf[1..]);

    // This shouldn't happen according to protocol
    let len = len.unwrap();

    // Assume and skip terminator
    index += 3;

    if len > 0 {
        Ok(Some(str::from_utf8(&buf[index..(index + len)])?.to_owned()))
    } else {
        Ok(None)
    }
}