Improve command line output for responses

next
Sayan Nandan 4 years ago
parent bad7b0999d
commit d6d764cfb9
No known key found for this signature in database
GPG Key ID: C31EFD7DDA12AEE0

28
Cargo.lock generated

@ -55,6 +55,7 @@ version = "0.4.0"
dependencies = [
"bytes",
"lazy_static",
"termion",
]
[[package]]
@ -257,6 +258,12 @@ dependencies = [
"libc",
]
[[package]]
name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
[[package]]
name = "parking_lot"
version = "0.11.0"
@ -360,6 +367,15 @@ version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
dependencies = [
"redox_syscall",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -428,6 +444,18 @@ dependencies = [
"tokio",
]
[[package]]
name = "termion"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905"
dependencies = [
"libc",
"numtoa",
"redox_syscall",
"redox_termios",
]
[[package]]
name = "tokio"
version = "0.2.22"

@ -29,7 +29,6 @@ use std::fmt;
/// Errors that may occur while parsing responses from the server
#[derive(Debug, PartialEq)]
pub enum ClientResult {
RespCode(RespCodes, usize),
InvalidResponse(usize),
Response(Vec<DataGroup>, usize),
Empty(usize),
@ -39,20 +38,7 @@ pub enum ClientResult {
impl fmt::Display for ClientResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ClientResult::*;
use RespCodes::*;
match self {
RespCode(r, _) => match r {
Okay => Ok(()),
NotFound => writeln!(f, "ERROR: Couldn't find the key"),
OverwriteError => writeln!(f, "ERROR: Existing values cannot be overwritten"),
PacketError => writeln!(f, "ERROR: An invalid request was sent"),
ActionError => writeln!(f, "ERROR: The action is not in the correct format"),
ServerError => writeln!(f, "ERROR: The server had an internal error"),
OtherError(e) => match e {
None => writeln!(f, "ERROR: An unknown error occurred"),
Some(e) => writeln!(f, "ERROR: {}", e),
},
},
InvalidResponse(_) => write!(f, "ERROR: The server sent an invalid response"),
Response(_, _) => unimplemented!(),
Empty(_) => write!(f, ""),

@ -77,16 +77,6 @@ impl Connection {
}
return;
}
x @ ClientResult::RespCode(_, _) => {
match x {
ClientResult::RespCode(_, f) => {
self.buffer.advance(f);
}
_ => unimplemented!(),
}
eprint!("{}", x);
return;
}
ClientResult::InvalidResponse(_) => {
self.buffer.clear();
eprintln!("{}", ClientResult::InvalidResponse(0));

@ -8,4 +8,5 @@ edition = "2018"
[dependencies]
lazy_static = "1.4.0"
bytes = "0.5.6"
bytes = "0.5.6"
termion = "*"

@ -23,6 +23,7 @@
//! The `de` module provides primitives for deserialization primitives for parsing
//! query and response packets
use crate::terrapipe::RespCodes;
use bytes::BytesMut;
use std::fmt;
use std::ops::Deref;
@ -184,32 +185,142 @@ pub struct DataGroup(pub Vec<String>);
impl fmt::Display for DataGroup {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use termion::{color, style};
/*
TODO(@ohsayan): Implement proper formatting for the response. That is,
for `!` print the respective error code, for `+` print the corresponding
array or single-value
*/
if self.0.len() == 0 {
if self.len() == 0 {
// The server returned a zero-sized array
return write!(f, "[]");
}
if self.0.len() == 1 {
return write!(f, "{}", &self.0[0][1..]);
}
let mut it = self.0.iter().peekable();
write!(f, "[")?;
while let Some(token) = it.next() {
if it.peek().is_some() {
write!(f, "\"{}\"", token)?;
write!(f, ", ")?;
} else {
write!(f, "\"{}\"", token)?;
write!(f, "]")?;
for token in self.iter() {
if token.len() == 0 {
write!(f, "\"\"")?;
continue;
}
let mut byter = token.bytes();
match byter.next().unwrap() {
b'!' => {
// This is an error
match byter.next() {
Some(tok) => match RespCodes::from_utf8(tok) {
Some(code) => {
use RespCodes::*;
match code {
Okay => write!(
f,
"{}(Okay){}",
color::Fg(color::Rgb(2, 117, 216)),
style::Reset
)?,
NotFound => write!(
f,
"{}ERROR: Couldn't find the key{}",
color::Fg(color::LightRed),
style::Reset
)?,
OverwriteError => {
write!(
f,
"{}ERROR: Existing values cannot be overwritten{}",
color::Fg(color::LightRed),
style::Reset
)?;
}
PacketError => {
write!(
f,
"{}ERROR: An invalid request was sent{}",
color::Fg(color::LightRed),
style::Reset
)?;
}
ActionError => write!(
f,
"{}ERROR: The action is not in the correct format{}",
color::Fg(color::LightRed),
style::Reset
)?,
ServerError => write!(
f,
"{}(Server Error){}",
color::Fg(color::LightRed),
style::Reset
)?,
OtherError(_) => {
let rem = byter.collect::<Vec<u8>>();
if rem.len() == 0 {
write!(
f,
"{}(Unknown Error){}",
color::Fg(color::LightRed),
style::Reset
)?;
} else {
write!(
f,
"{}({}){}",
color::Fg(color::LightRed),
String::from_utf8_lossy(&rem),
style::Reset
)?;
}
}
}
}
None => {
let rem = byter.collect::<Vec<u8>>();
if rem.len() == 0 {
write!(
f,
"{}(Unknown Error){}",
color::Fg(color::LightRed),
style::Reset
)?;
} else {
write!(
f,
"{}({}{}){}",
tok,
color::Fg(color::LightRed),
String::from_utf8_lossy(&rem),
style::Reset
)?;
}
}
},
None => write!(
f,
"{}(Unknown Error){}",
color::Fg(color::LightRed),
style::Reset
)?,
}
}
b'+' => {
// This is a positive response
let rem = byter.collect::<Vec<u8>>();
write!(f, "\"{}\"", String::from_utf8_lossy(&rem))?;
}
x @ _ => {
// Unknown response
let rem = byter.collect::<Vec<u8>>();
write!(
f,
"{}Unknown response: \"{}{}\"{}",
color::Fg(color::Rgb(255, 69, 0)),
x,
String::from_utf8_lossy(&rem),
style::Reset
)?;
}
}
}
Ok(())
}
}
impl IntoIterator for DataGroup {
type Item = String;
type IntoIter = std::vec::IntoIter<Self::Item>;

Loading…
Cancel
Save