-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
472 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"type": "lldb", | ||
"request": "launch", | ||
"name": "Debug", | ||
"program": "${workspaceFolder}/<executable file>", | ||
"args": [], | ||
"cwd": "${workspaceFolder}" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use crate::{CommandError, CommandExecutor, RespArray, RespFrame}; | ||
|
||
use super::{extract_args, validate_command}; | ||
|
||
#[derive(Debug)] | ||
pub struct Echo { | ||
pub echo: RespFrame, | ||
} | ||
|
||
impl CommandExecutor for Echo { | ||
fn execute(self) -> RespFrame { | ||
self.echo | ||
} | ||
} | ||
|
||
impl TryFrom<RespArray> for Echo { | ||
type Error = CommandError; | ||
fn try_from(value: RespArray) -> Result<Self, Self::Error> { | ||
validate_command(&value, &["echo"], 1, super::ArgsCheckRule::Equal)?; | ||
|
||
let mut args = extract_args(value, 1)?.into_iter(); | ||
match args.next() { | ||
Some(echo) => Ok(Echo { echo }), | ||
_ => Err(CommandError::InvalidArgument("Invalid echo".to_string())), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::{BulkString, Command, RespArray, RespFrame}; | ||
|
||
use super::*; | ||
use anyhow::Result; | ||
|
||
#[test] | ||
fn test_echo() -> Result<()> { | ||
let frame: RespFrame = Some(RespArray::new(vec![ | ||
Some(BulkString::new("echo".to_string())).into(), | ||
Some(BulkString::new("hello".to_string())).into(), | ||
])) | ||
.into(); | ||
|
||
let echo = Command::try_from(frame)?; | ||
let ret = echo.execute(); | ||
assert_eq!(ret, Some(BulkString::new("hello".to_string())).into()); | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
use crate::{BulkString, CommandError, CommandExecutor, RespArray, RespFrame, RespNull}; | ||
|
||
use super::{extract_args, validate_command}; | ||
|
||
#[derive(Debug)] | ||
pub struct HmGet { | ||
pub key: String, | ||
pub members: Vec<String>, | ||
} | ||
|
||
impl CommandExecutor for HmGet { | ||
fn execute(self) -> RespFrame { | ||
println!("{:?}", self); | ||
let mut result = RespArray::new(vec![]); | ||
for member in self.members.iter() { | ||
match member.as_str() { | ||
"field1" => result.push(Some(BulkString::new("field1".to_string())).into()), | ||
"field2" => result.push(Some(BulkString::new("field2".to_string())).into()), | ||
_ => result.push(RespFrame::Null(RespNull {})), | ||
} | ||
} | ||
RespFrame::Array(Some(result)) | ||
} | ||
} | ||
|
||
impl TryFrom<RespArray> for HmGet { | ||
type Error = CommandError; | ||
fn try_from(value: RespArray) -> Result<Self, Self::Error> { | ||
validate_command(&value, &["hmget"], 2, super::ArgsCheckRule::EqualOrGreater)?; | ||
|
||
let mut args = extract_args(value, 1)?.into_iter(); | ||
let key = match args.next() { | ||
Some(RespFrame::BulkString(Some(key))) => Ok(String::from_utf8(key.0)?), | ||
_ => Err(CommandError::InvalidArgument("Invalid hmget".to_string())), | ||
}?; | ||
|
||
let members = args | ||
.filter_map(|arg| { | ||
if let RespFrame::BulkString(Some(key)) = arg { | ||
String::from_utf8(key.0).ok() | ||
} else { | ||
None | ||
} | ||
}) | ||
.collect::<Vec<String>>(); | ||
|
||
if members.is_empty() { | ||
return Err(CommandError::InvalidArgument("Invalid hmget".to_string())); | ||
} | ||
|
||
Ok(HmGet { key, members }) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::{BulkString, Command, RespArray, RespFrame}; | ||
|
||
use super::*; | ||
use anyhow::Result; | ||
|
||
#[test] | ||
fn test_hmget() -> Result<()> { | ||
let frame: RespFrame = Some(RespArray::new(vec![ | ||
Some(BulkString::new("hmget".to_string())).into(), | ||
Some(BulkString::new("myhash".to_string())).into(), | ||
Some(BulkString::new("field1".to_string())).into(), | ||
Some(BulkString::new("field2".to_string())).into(), | ||
Some(BulkString::new("nofield".to_string())).into(), | ||
])) | ||
.into(); | ||
|
||
let sadd = Command::try_from(frame)?; | ||
let ret = sadd.execute(); | ||
|
||
assert_eq!( | ||
ret, | ||
Some(RespArray::new(vec![ | ||
Some(BulkString::new("field1".to_string())).into(), | ||
Some(BulkString::new("field2".to_string())).into(), | ||
RespNull::new().into(), | ||
])) | ||
.into() | ||
); | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use crate::{CommandError, CommandExecutor, RespArray, RespFrame}; | ||
|
||
use super::{extract_args, validate_command}; | ||
|
||
#[derive(Debug)] | ||
pub struct SAdd { | ||
pub key: String, | ||
pub members: RespArray, | ||
} | ||
|
||
impl CommandExecutor for SAdd { | ||
fn execute(self) -> RespFrame { | ||
println!("{:?}", self); | ||
let len = self.members.len() as i64; | ||
len.into() | ||
} | ||
} | ||
|
||
impl TryFrom<RespArray> for SAdd { | ||
type Error = CommandError; | ||
fn try_from(value: RespArray) -> Result<Self, Self::Error> { | ||
validate_command(&value, &["sadd"], 2, super::ArgsCheckRule::EqualOrGreater)?; | ||
|
||
let mut args = extract_args(value, 1)?.into_iter(); | ||
let key = match args.next() { | ||
Some(RespFrame::BulkString(Some(key))) => Ok(String::from_utf8(key.0)?), | ||
_ => Err(CommandError::InvalidArgument("Invalid sadd".to_string())), | ||
}?; | ||
|
||
let mut members = RespArray::new(vec![]); | ||
for arg in args { | ||
members.push(arg) | ||
} | ||
|
||
Ok(SAdd { key, members }) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::{BulkString, Command, RespArray, RespFrame}; | ||
|
||
use super::*; | ||
use anyhow::Result; | ||
|
||
#[test] | ||
fn test_sadd() -> Result<()> { | ||
let frame: RespFrame = Some(RespArray::new(vec![ | ||
Some(BulkString::new("sadd".to_string())).into(), | ||
Some(BulkString::new("myset".to_string())).into(), | ||
Some(BulkString::new("A".to_string())).into(), | ||
Some(BulkString::new("B".to_string())).into(), | ||
Some(BulkString::new("C".to_string())).into(), | ||
])) | ||
.into(); | ||
|
||
let sadd = Command::try_from(frame)?; | ||
let ret = sadd.execute(); | ||
assert_eq!(ret, 3.into()); | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use crate::{CommandError, CommandExecutor, RespArray, RespFrame}; | ||
|
||
use super::{extract_args, validate_command}; | ||
|
||
#[derive(Debug)] | ||
pub struct SisMember { | ||
pub key: String, | ||
pub member: RespFrame, | ||
} | ||
|
||
impl CommandExecutor for SisMember { | ||
fn execute(self) -> RespFrame { | ||
println!("{:?}", self); | ||
1.into() | ||
} | ||
} | ||
|
||
impl TryFrom<RespArray> for SisMember { | ||
type Error = CommandError; | ||
fn try_from(value: RespArray) -> Result<Self, Self::Error> { | ||
validate_command( | ||
&value, | ||
&["sismember"], | ||
2, | ||
super::ArgsCheckRule::EqualOrGreater, | ||
)?; | ||
|
||
let mut args = extract_args(value, 1)?.into_iter(); | ||
match (args.next(), args.next()) { | ||
(Some(RespFrame::BulkString(Some(key))), Some(member)) => Ok(SisMember { | ||
key: String::from_utf8(key.0)?, | ||
member, | ||
}), | ||
_ => Err(CommandError::InvalidArgument("Invalid echo".to_string())), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::{BulkString, Command, RespArray, RespFrame}; | ||
|
||
use super::*; | ||
use anyhow::Result; | ||
|
||
#[test] | ||
fn test_sismember() -> Result<()> { | ||
let frame: RespFrame = Some(RespArray::new(vec![ | ||
Some(BulkString::new("sismember".to_string())).into(), | ||
Some(BulkString::new("myset".to_string())).into(), | ||
Some(BulkString::new("A".to_string())).into(), | ||
])) | ||
.into(); | ||
|
||
let sis_member = Command::try_from(frame)?; | ||
let ret = sis_member.execute(); | ||
assert_eq!(ret, 1.into()); | ||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.