2014-02-14 21:21:17 -06:00
|
|
|
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
// ignore-test needs networking
|
|
|
|
|
|
|
|
extern crate extra;
|
|
|
|
|
|
|
|
use extra::net::tcp::TcpSocketBuf;
|
|
|
|
|
|
|
|
use std::io;
|
2015-03-25 19:06:52 -05:00
|
|
|
use std::isize;
|
2014-02-14 21:21:17 -06:00
|
|
|
|
|
|
|
use std::io::{ReaderUtil,WriterUtil};
|
|
|
|
|
|
|
|
enum Result {
|
|
|
|
Nil,
|
2015-03-25 19:06:52 -05:00
|
|
|
Int(isize),
|
2014-02-14 21:21:17 -06:00
|
|
|
Data(~[u8]),
|
|
|
|
List(~[Result]),
|
2014-05-22 18:57:53 -05:00
|
|
|
Error(String),
|
|
|
|
Status(String)
|
2014-02-14 21:21:17 -06:00
|
|
|
}
|
|
|
|
|
2015-03-25 19:06:52 -05:00
|
|
|
priv fn parse_data(len: usize, io: @io::Reader) -> Result {
|
2014-02-14 21:21:17 -06:00
|
|
|
let res =
|
|
|
|
if (len > 0) {
|
2015-03-25 19:06:52 -05:00
|
|
|
let bytes = io.read_bytes(len as usize);
|
2014-02-14 21:21:17 -06:00
|
|
|
assert_eq!(bytes.len(), len);
|
|
|
|
Data(bytes)
|
|
|
|
} else {
|
|
|
|
Data(~[])
|
|
|
|
};
|
|
|
|
assert_eq!(io.read_char(), '\r');
|
|
|
|
assert_eq!(io.read_char(), '\n');
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2015-03-25 19:06:52 -05:00
|
|
|
priv fn parse_list(len: usize, io: @io::Reader) -> Result {
|
2014-02-14 21:21:17 -06:00
|
|
|
let mut list: ~[Result] = ~[];
|
2015-01-26 14:46:12 -06:00
|
|
|
for _ in 0..len {
|
2014-02-14 21:21:17 -06:00
|
|
|
let v = match io.read_char() {
|
|
|
|
'$' => parse_bulk(io),
|
|
|
|
':' => parse_int(io),
|
2014-10-09 14:17:22 -05:00
|
|
|
_ => panic!()
|
2014-02-14 21:21:17 -06:00
|
|
|
};
|
|
|
|
list.push(v);
|
|
|
|
}
|
|
|
|
return List(list);
|
|
|
|
}
|
|
|
|
|
2014-05-22 18:57:53 -05:00
|
|
|
priv fn chop(s: String) -> String {
|
2014-07-16 15:37:28 -05:00
|
|
|
s.slice(0, s.len() - 1).to_string()
|
2014-02-14 21:21:17 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
priv fn parse_bulk(io: @io::Reader) -> Result {
|
2015-03-25 19:06:52 -05:00
|
|
|
match from_str::<isize>(chop(io.read_line())) {
|
2014-10-09 14:17:22 -05:00
|
|
|
None => panic!(),
|
2014-02-14 21:21:17 -06:00
|
|
|
Some(-1) => Nil,
|
2015-03-25 19:06:52 -05:00
|
|
|
Some(len) if len >= 0 => parse_data(len as usize, io),
|
2014-10-09 14:17:22 -05:00
|
|
|
Some(_) => panic!()
|
2014-02-14 21:21:17 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
priv fn parse_multi(io: @io::Reader) -> Result {
|
2015-03-25 19:06:52 -05:00
|
|
|
match from_str::<isize>(chop(io.read_line())) {
|
2014-10-09 14:17:22 -05:00
|
|
|
None => panic!(),
|
2014-02-14 21:21:17 -06:00
|
|
|
Some(-1) => Nil,
|
|
|
|
Some(0) => List(~[]),
|
2015-03-25 19:06:52 -05:00
|
|
|
Some(len) if len >= 0 => parse_list(len as usize, io),
|
2014-10-09 14:17:22 -05:00
|
|
|
Some(_) => panic!()
|
2014-02-14 21:21:17 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
priv fn parse_int(io: @io::Reader) -> Result {
|
2015-03-25 19:06:52 -05:00
|
|
|
match from_str::<isize>(chop(io.read_line())) {
|
2014-10-09 14:17:22 -05:00
|
|
|
None => panic!(),
|
2014-02-14 21:21:17 -06:00
|
|
|
Some(i) => Int(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
priv fn parse_response(io: @io::Reader) -> Result {
|
|
|
|
match io.read_char() {
|
|
|
|
'$' => parse_bulk(io),
|
|
|
|
'*' => parse_multi(io),
|
|
|
|
'+' => Status(chop(io.read_line())),
|
|
|
|
'-' => Error(chop(io.read_line())),
|
|
|
|
':' => parse_int(io),
|
2014-10-09 14:17:22 -05:00
|
|
|
_ => panic!()
|
2014-02-14 21:21:17 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-21 05:39:03 -05:00
|
|
|
priv fn cmd_to_string(cmd: ~[String]) -> String {
|
2014-05-25 05:10:11 -05:00
|
|
|
let mut res = "*".to_string();
|
2014-06-21 05:39:03 -05:00
|
|
|
res.push_str(cmd.len().to_string());
|
2014-02-14 21:21:17 -06:00
|
|
|
res.push_str("\r\n");
|
2015-01-31 11:20:46 -06:00
|
|
|
for s in &cmd {
|
2014-06-21 05:39:03 -05:00
|
|
|
res.push_str(["$".to_string(), s.len().to_string(), "\r\n".to_string(),
|
2014-05-25 05:10:11 -05:00
|
|
|
(*s).clone(), "\r\n".to_string()].concat() );
|
2014-02-14 21:21:17 -06:00
|
|
|
}
|
|
|
|
res
|
|
|
|
}
|
|
|
|
|
2014-05-22 18:57:53 -05:00
|
|
|
fn query(cmd: ~[String], sb: TcpSocketBuf) -> Result {
|
2014-06-21 05:39:03 -05:00
|
|
|
let cmd = cmd_to_string(cmd);
|
2014-02-14 21:21:17 -06:00
|
|
|
//println!("{}", cmd);
|
|
|
|
sb.write_str(cmd);
|
|
|
|
let res = parse_response(@sb as @io::Reader);
|
|
|
|
res
|
|
|
|
}
|
|
|
|
|
2014-05-22 18:57:53 -05:00
|
|
|
fn query2(cmd: ~[String]) -> Result {
|
2014-06-21 05:39:03 -05:00
|
|
|
let _cmd = cmd_to_string(cmd);
|
2014-05-25 05:10:11 -05:00
|
|
|
io::with_str_reader("$3\r\nXXX\r\n".to_string())(|sb| {
|
2014-02-14 21:21:17 -06:00
|
|
|
let res = parse_response(@sb as @io::Reader);
|
2014-10-14 20:07:11 -05:00
|
|
|
println!("{}", res);
|
2014-02-14 21:21:17 -06:00
|
|
|
res
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn main() {
|
|
|
|
}
|