use crate::{value_try_from, value_vec_try_from}; use redis_zero_parser::Value as ParsedValue; use bytes::{Bytes, BytesMut}; use std::convert::TryFrom; #[derive(Debug, PartialEq, Clone)] pub enum Value { Array(Vec), Blob(Bytes), String(String), Err(String, String), Integer(i64), Boolean(bool), Float(f64), BigInteger(i128), Null, } impl From<&Value> for Vec { fn from(value: &Value) -> Vec { match value { Value::Null => b"*-1\r\n".to_vec(), Value::Array(x) => { let mut s: Vec = format!("*{}\r\n", x.len()).into(); for i in x.iter() { let b: Vec = i.into(); s.extend(b); } s.to_vec() } Value::Integer(x) => format!(":{}\r\n", x).into(), Value::BigInteger(x) => format!("({}\r\n", x).into(), Value::Blob(x) => { let s = format!("${}\r\n", x.len()); let mut s: BytesMut = s.as_str().as_bytes().into(); s.extend_from_slice(&x); s.extend_from_slice(b"\r\n"); s.to_vec() } _ => b"*-1\r\n".to_vec(), } } } impl From for Vec { fn from(value: Value) -> Vec { (&value).into() } } impl<'a> TryFrom<&ParsedValue<'a>> for Value { type Error = &'static str; fn try_from(value: &ParsedValue) -> Result { Ok(match value { ParsedValue::String(x) => Self::String(x.to_string()), ParsedValue::Blob(x) => Self::Blob(Bytes::copy_from_slice(*x)), ParsedValue::Array(x) => { Self::Array(x.iter().map(|x| Value::try_from(x).unwrap()).collect()) } ParsedValue::Boolean(x) => Self::Boolean(*x), ParsedValue::BigInteger(x) => Self::BigInteger(*x), ParsedValue::Integer(x) => Self::Integer(*x), ParsedValue::Float(x) => Self::Float(*x), ParsedValue::Error(x, y) => Self::Err(x.to_string(), y.to_string()), ParsedValue::Null => Self::Null, }) } } value_try_from!(i64, Value::Integer); value_try_from!(i128, Value::BigInteger); impl From<&str> for Value { fn from(value: &str) -> Value { Value::Blob(Bytes::copy_from_slice(value.as_bytes())) } } value_vec_try_from!(&str);