redis_oxide/core/
value.rs1use crate::core::error::{RedisError, RedisResult};
4use bytes::Bytes;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum RespValue {
9    SimpleString(String),
11    Error(String),
13    Integer(i64),
15    BulkString(Bytes),
17    Null,
19    Array(Vec<RespValue>),
21}
22
23impl RespValue {
24    pub fn as_string(&self) -> RedisResult<String> {
30        match self {
31            Self::SimpleString(s) => Ok(s.clone()),
32            Self::BulkString(b) => String::from_utf8(b.to_vec())
33                .map_err(|e| RedisError::Type(format!("Invalid UTF-8: {e}"))),
34            Self::Null => Err(RedisError::Type("Value is null".to_string())),
35            _ => Err(RedisError::Type(format!(
36                "Cannot convert {self:?} to string"
37            ))),
38        }
39    }
40
41    pub fn as_int(&self) -> RedisResult<i64> {
47        match self {
48            Self::Integer(i) => Ok(*i),
49            Self::BulkString(b) => {
50                let s = String::from_utf8(b.to_vec())
51                    .map_err(|e| RedisError::Type(format!("Invalid UTF-8: {e}")))?;
52                s.parse::<i64>()
53                    .map_err(|e| RedisError::Type(format!("Cannot parse integer: {e}")))
54            }
55            _ => Err(RedisError::Type(format!(
56                "Cannot convert {self:?} to integer"
57            ))),
58        }
59    }
60
61    pub fn as_bytes(&self) -> RedisResult<Bytes> {
67        match self {
68            Self::BulkString(b) => Ok(b.clone()),
69            Self::SimpleString(s) => Ok(Bytes::from(s.as_bytes().to_vec())),
70            Self::Null => Err(RedisError::Type("Value is null".to_string())),
71            _ => Err(RedisError::Type(format!(
72                "Cannot convert {self:?} to bytes"
73            ))),
74        }
75    }
76
77    pub fn as_array(&self) -> RedisResult<Vec<Self>> {
83        match self {
84            Self::Array(arr) => Ok(arr.clone()),
85            _ => Err(RedisError::Type(format!(
86                "Cannot convert {self:?} to array"
87            ))),
88        }
89    }
90
91    #[must_use]
93    pub const fn is_null(&self) -> bool {
94        matches!(self, Self::Null)
95    }
96
97    #[must_use]
99    pub const fn is_error(&self) -> bool {
100        matches!(self, Self::Error(_))
101    }
102
103    #[must_use]
105    pub fn into_error(self) -> Option<String> {
106        match self {
107            Self::Error(msg) => Some(msg),
108            _ => None,
109        }
110    }
111}
112
113impl From<String> for RespValue {
114    fn from(s: String) -> Self {
115        Self::BulkString(Bytes::from(s.into_bytes()))
116    }
117}
118impl From<&str> for RespValue {
119    fn from(s: &str) -> Self {
120        Self::BulkString(Bytes::from(s.as_bytes().to_vec()))
121    }
122}
123impl From<i64> for RespValue {
124    fn from(i: i64) -> Self {
125        Self::Integer(i)
126    }
127}
128impl From<Vec<u8>> for RespValue {
129    fn from(b: Vec<u8>) -> Self {
130        Self::BulkString(Bytes::from(b))
131    }
132}
133impl From<Bytes> for RespValue {
134    fn from(b: Bytes) -> Self {
135        Self::BulkString(b)
136    }
137}