Skip to content

Commit

Permalink
feat: add command
Browse files Browse the repository at this point in the history
  • Loading branch information
care0717 committed Jun 12, 2021
1 parent 933ba0a commit 4331493
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 34 deletions.
16 changes: 11 additions & 5 deletions src/bin/client.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::io::{stdout, BufRead, BufReader, BufWriter, Error, Write};
use std::net::TcpStream;
use std::io::{Error, BufReader, BufWriter, Write, stdout, BufRead};

fn main() {
let stream = TcpStream::connect("127.0.0.1:33333");
match stream {
Ok(s) => {
handler(s).unwrap_or_else(|error| eprintln!("{:?}", error));
}
Err(e) => {eprintln!("error: {}", e)}
Err(e) => {
eprintln!("error: {}", e)
}
}
}

Expand All @@ -19,7 +21,11 @@ fn handler(stream: TcpStream) -> Result<(), Error> {

std::io::stdin().read_line(&mut input)?;

if input.split_whitespace().next().map_or(false, |v| v == "set") {
if input
.split_whitespace()
.next()
.map_or(false, |v| v == "set")
{
let mut body = String::new();
std::io::stdin().read_line(&mut body)?;
input = input + &*body;
Expand All @@ -33,9 +39,9 @@ fn handler(stream: TcpStream) -> Result<(), Error> {
let nbytes = reader.read_line(&mut return_value)?;
if nbytes == 0 {
println!("receive EOF");
break
break;
}
print!("{}", return_value);
}
return Ok(())
return Ok(());
}
17 changes: 10 additions & 7 deletions src/bin/server.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::io::{BufWriter, Write, Error, stdout, ErrorKind};
use lsm_engine::decoder;
use std::io::{stdout, BufWriter, Error, ErrorKind, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;
use lsm_engine::decoder;

fn main() {
let listener = TcpListener::bind("0.0.0.0:33333").expect("Error. failed to bind.");
for streams in listener.incoming() {
match streams {
Err(e) => { eprintln!("error: {}", e)},
Err(e) => {
eprintln!("error: {}", e)
}
Ok(stream) => {
thread::spawn(move || {
handler(stream).unwrap_or_else(|error| eprintln!("{:?}", error));
Expand All @@ -24,15 +26,16 @@ fn handler(stream: TcpStream) -> Result<(), Error> {
loop {
let decoded = decoder.decode();
match decoded {
Ok(d) => {
print!("{}", d);
writer.write(d.as_bytes())?;
Ok(c) => {
let result = c.execute();
print!("{}", result);
writer.write(result.as_bytes())?;
writer.flush()?;
}
Err(e) => {
print!("{}", e);
if e.kind() == ErrorKind::UnexpectedEof {
return Err(e)
return Err(e);
}
writer.write(format!("{}\n", e.to_string()).as_bytes())?;
writer.flush()?;
Expand Down
25 changes: 25 additions & 0 deletions src/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::command::Command::{Get, Set};

pub enum Command {
Set { key: String, body: String },
Get { key: String },
}

pub fn new_command_set<'a>(key: String, body: String) -> Command {
return Set { key, body };
}

pub fn new_command_get(key: String) -> Command {
return Get { key };
}

impl Command {
pub fn execute(self) -> String {
match self {
Command::Set { key, body } => {
format!("{}\n", key)
}
Command::Get { key } => format!("{}\n", key),
}
}
}
53 changes: 31 additions & 22 deletions src/decoder.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,67 @@
use std::io::{BufRead, Error, ErrorKind, Read, BufReader};
use crate::command;
use std::io::{BufRead, BufReader, Error, ErrorKind, Read};

pub struct Decoder<R: Read> {
reader: BufReader<R>
reader: BufReader<R>,
}

pub fn new<R: Read>(reader: R) -> Decoder<R> {
let r = BufReader::new(reader);
Decoder{reader: r}
Decoder { reader: r }
}

impl<R: Read> Decoder<R> {
pub fn decode(&mut self) -> Result<&str, Error> {
pub fn decode(&mut self) -> Result<command::Command, Error> {
let mut buf = String::new();
let nbytes = self.reader.read_line(&mut buf)?;
if nbytes == 0 {
return Err(Error::new(ErrorKind::UnexpectedEof, "got eof\n"))
return Err(Error::new(ErrorKind::UnexpectedEof, "got eof\n"));
}
let commands: Vec<&str> = buf.trim().split_whitespace().collect();


commands.clone().first()
commands
.clone()
.first()
.ok_or(Error::new(ErrorKind::InvalidInput, "no content\n"))
.and_then(
move |c| match c {
.and_then(move |c| match c {
&"set" => self.decode_set(commands),
&"get" => self.decode_get(commands),
_ => Err(Error::new(ErrorKind::InvalidInput, format!("unknown command: {}\n", c)))
}
)
_ => Err(Error::new(
ErrorKind::InvalidInput,
format!("unknown command: {}\n", c),
)),
})
}

fn decode_set(&mut self, commands: Vec<&str>) -> Result<&str, Error> {
fn decode_set(&mut self, commands: Vec<&str>) -> Result<command::Command, Error> {
if commands.len() != 5 {
return Err(Error::new(ErrorKind::InvalidInput, "set command length must be 5\n"))
return Err(Error::new(
ErrorKind::InvalidInput,
"set command length must be 5\n",
));
}
let _key = commands[1];
let _flag = commands[2];
let _exptime = commands[3];
let _bytes = commands[4].parse::<usize>().map_err(|e| Error::new(ErrorKind::InvalidInput, e))?;

let _bytes = commands[4]
.parse::<usize>()
.map_err(|e| Error::new(ErrorKind::InvalidInput, e))?;
let mut buf = String::new();
let nbytes = self.reader.read_line(&mut buf)?;
if nbytes == 0 {
return Err(Error::new(ErrorKind::UnexpectedEof, "got eof\n"))
return Err(Error::new(ErrorKind::UnexpectedEof, "got eof\n"));
}
Ok("STORED\n")
Ok(command::new_command_set(_key.to_string(), buf))
}

fn decode_get(&mut self, commands: Vec<&str>) -> Result<&str, Error> {
fn decode_get(&mut self, commands: Vec<&str>) -> Result<command::Command, Error> {
if commands.len() != 2 {
return Err(Error::new(ErrorKind::InvalidInput, "get command length must be 2\n"))
return Err(Error::new(
ErrorKind::InvalidInput,
"get command length must be 2\n",
));
}
let _key = commands[1];
Ok("key\n")
Ok(command::new_command_get(_key.to_string()))
}
}

1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod command;
pub mod decoder;

0 comments on commit 4331493

Please # to comment.