redis_driver/resp/
command_arg.rs

1use crate::{Error, Result};
2use std::{fmt, str::from_utf8_unchecked};
3
4use super::BulkString;
5
6#[derive(Clone, PartialEq)]
7pub enum CommandArg {
8    Str(&'static str),
9    String(String),
10    Binary(Vec<u8>),
11    Integer(i64),
12    F32(f32),
13    F64(f64),
14    Nil,
15}
16
17impl CommandArg {
18    #[must_use]
19    #[inline]
20    pub fn len(&self) -> usize {
21        match self {
22            CommandArg::Str(s) => s.len(),
23            CommandArg::String(s) => s.len(),
24            CommandArg::Binary(s) => s.len(),
25            CommandArg::Integer(_) | CommandArg::F32(_) | CommandArg::F64(_) | CommandArg::Nil => {
26                unimplemented!()
27            }
28        }
29    }
30
31    #[must_use]
32    #[inline]
33    pub fn is_empty(&self) -> bool {
34        self.len() == 0
35    }
36
37    #[must_use]
38    #[inline]
39    pub fn as_bytes(&self) -> &[u8] {
40        match self {
41            CommandArg::Str(s) => s.as_bytes(),
42            CommandArg::String(s) => s.as_bytes(),
43            CommandArg::Binary(s) => s,
44            CommandArg::Integer(_) | CommandArg::F32(_) | CommandArg::F64(_) | CommandArg::Nil => {
45                unimplemented!()
46            }
47        }
48    }
49
50    pub fn to_usize(&self) -> Result<usize> {
51        match self {
52            CommandArg::Str(s) => match s.parse::<usize>() {
53                Ok(u) => Ok(u),
54                Err(e) => Err(Error::Client(e.to_string())),
55            },
56            CommandArg::String(s) => match s.parse::<usize>() {
57                Ok(u) => Ok(u),
58                Err(e) => Err(Error::Client(e.to_string())),
59            },
60            CommandArg::Binary(b) => unsafe {
61                match from_utf8_unchecked(b).parse::<usize>() {
62                    Ok(u) => Ok(u),
63                    Err(e) => Err(Error::Client(e.to_string())),
64                }
65            },
66            CommandArg::Integer(i) => Ok(*i as usize),
67            CommandArg::F32(f) => Ok(*f as usize),
68            CommandArg::F64(f) => Ok(*f as usize),
69            CommandArg::Nil => Ok(0),
70        }
71    }
72}
73
74impl From<char> for CommandArg {
75    #[inline]
76    fn from(ch: char) -> Self {
77        Self::String(ch.to_string())
78    }
79}
80
81impl From<&'static str> for CommandArg {
82    #[inline]
83    fn from(str: &'static str) -> Self {
84        Self::Str(str)
85    }
86}
87
88impl From<String> for CommandArg {
89    #[inline]
90    fn from(string: String) -> Self {
91        Self::String(string)
92    }
93}
94
95impl From<i64> for CommandArg {
96    #[inline]
97    fn from(i: i64) -> Self {
98        Self::Integer(i)
99    }
100}
101
102impl From<u64> for CommandArg {
103    #[inline]
104    fn from(u: u64) -> Self {
105        Self::Integer(u as i64)
106    }
107}
108
109impl From<i32> for CommandArg {
110    #[inline]
111    fn from(i: i32) -> Self {
112        Self::Integer(i64::from(i))
113    }
114}
115
116impl From<u32> for CommandArg {
117    #[inline]
118    fn from(u: u32) -> Self {
119        Self::Integer(i64::from(u))
120    }
121}
122
123impl From<i16> for CommandArg {
124    #[inline]
125    fn from(i: i16) -> Self {
126        Self::Integer(i64::from(i))
127    }
128}
129
130impl From<u16> for CommandArg {
131    #[inline]
132    fn from(u: u16) -> Self {
133        Self::Integer(i64::from(u))
134    }
135}
136
137impl From<isize> for CommandArg {
138    #[inline]
139    fn from(i: isize) -> Self {
140        Self::Integer(i as i64)
141    }
142}
143
144impl From<usize> for CommandArg {
145    #[inline]
146    fn from(u: usize) -> Self {
147        Self::Integer(u as i64)
148    }
149}
150
151impl From<f32> for CommandArg {
152    #[inline]
153    fn from(f: f32) -> Self {
154        Self::F32(f)
155    }
156}
157
158impl From<f64> for CommandArg {
159    #[inline]
160    fn from(f: f64) -> Self {
161        Self::F64(f)
162    }
163}
164
165impl From<BulkString> for CommandArg {
166    #[inline]
167    fn from(bs: BulkString) -> Self {
168        Self::Binary(bs.0)
169    }   
170}
171
172impl From<CommandArg> for Result<String> {
173    #[inline]
174    fn from(bs: CommandArg) -> Self {
175        match bs {
176            CommandArg::Str(s) => Ok(s.to_owned()),
177            CommandArg::String(s) => Ok(s),
178            CommandArg::Binary(s) => String::from_utf8(s).map_err(|e| Error::Client(e.to_string())),
179            CommandArg::Integer(i) => Ok(i.to_string()),
180            CommandArg::F32(f) => Ok(f.to_string()),
181            CommandArg::F64(f) => Ok(f.to_string()),
182            CommandArg::Nil => Ok(String::from("")),
183        }
184    }
185}
186
187impl ToString for CommandArg {
188    fn to_string(&self) -> String {
189        match self {
190            CommandArg::Str(s) => (*s).to_owned(),
191            CommandArg::String(s) => s.clone(),
192            CommandArg::Binary(s) => String::from_utf8_lossy(s).into_owned(),
193            CommandArg::Integer(i) => i.to_string(),
194            CommandArg::F32(f) => f.to_string(),
195            CommandArg::F64(f) => f.to_string(),
196            CommandArg::Nil => String::from(""),
197        }
198    }
199}
200
201impl fmt::Debug for CommandArg {
202    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203        match self {
204            Self::Str(arg0) => f.debug_tuple("Str").field(arg0).finish(),
205            Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(),
206            Self::Binary(arg0) => f
207                .debug_tuple("Binary")
208                .field(&String::from_utf8_lossy(arg0).into_owned())
209                .finish(),
210            Self::Integer(arg0) => f.debug_tuple("Integer").field(arg0).finish(),
211            Self::F32(arg0) => f.debug_tuple("F32").field(arg0).finish(),
212            Self::F64(arg0) => f.debug_tuple("F64").field(arg0).finish(),
213            Self::Nil => write!(f, "Nil"),
214        }
215    }
216}
217
218impl PartialEq<String> for CommandArg {
219    fn eq(&self, other: &String) -> bool {
220        match self {
221            CommandArg::Str(s) => *other == *s,
222            CommandArg::String(s) => *other == *s,
223            CommandArg::Binary(s) => unsafe { *other == core::str::from_utf8_unchecked(s) },
224            CommandArg::Integer(i) => *other == i.to_string(),
225            CommandArg::F32(f) => *other == f.to_string(),
226            CommandArg::F64(f) => *other == f.to_string(),
227            CommandArg::Nil => other.is_empty(),
228        }
229    }
230}
231
232impl PartialEq<&str> for CommandArg {
233    fn eq(&self, other: &&str) -> bool {
234        match self {
235            CommandArg::Str(s) => *other == *s,
236            CommandArg::String(s) => *other == s,
237            CommandArg::Binary(s) => unsafe { *other == core::str::from_utf8_unchecked(s) },
238            CommandArg::Integer(i) => *other == i.to_string(),
239            CommandArg::F32(f) => *other == f.to_string(),
240            CommandArg::F64(f) => *other == f.to_string(),
241            CommandArg::Nil => other.is_empty(),
242        }
243    }
244}