parent
22445c2144
commit
3b87f4e94e
3 changed files with 34 additions and 4 deletions
|
@ -3,6 +3,7 @@ use csv;
|
||||||
use framed;
|
use framed;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std;
|
use std;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -16,6 +17,9 @@ pub enum Error {
|
||||||
#[error(non_std)]
|
#[error(non_std)]
|
||||||
Framed(framed::Error),
|
Framed(framed::Error),
|
||||||
|
|
||||||
|
/// Error in library `std::io`.
|
||||||
|
Io(io::Error),
|
||||||
|
|
||||||
/// Error in library `serde_json`.
|
/// Error in library `serde_json`.
|
||||||
SerdeJson(serde_json::Error),
|
SerdeJson(serde_json::Error),
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ mod error;
|
||||||
use error::{Error, Result};
|
use error::{Error, Result};
|
||||||
|
|
||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
use std::io::{stdin, stdout};
|
use std::io::{stdin, stdout, stderr, Write};
|
||||||
|
|
||||||
arg_enum! {
|
arg_enum! {
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
@ -58,18 +58,29 @@ fn try() -> Result<()> {
|
||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
// Note: Output is flushed after each line so output on stdout
|
||||||
|
// and messages on stderr are in sync.
|
||||||
|
|
||||||
let res = r.recv();
|
let res = r.recv();
|
||||||
match res {
|
match res {
|
||||||
Ok(v) => match out_fmt {
|
Ok(v) => match out_fmt {
|
||||||
OutputFormat::Csv => csvw.as_mut()
|
OutputFormat::Csv => {
|
||||||
.expect("Should've been initialized")
|
let csvw = csvw.as_mut()
|
||||||
.serialize(&v)?,
|
.expect("Should've been initialized");
|
||||||
|
csvw.serialize(&v)?;
|
||||||
|
csvw.flush()?;
|
||||||
|
}
|
||||||
OutputFormat::Debug => println!("{:#?}", v),
|
OutputFormat::Debug => println!("{:#?}", v),
|
||||||
OutputFormat::Json => {
|
OutputFormat::Json => {
|
||||||
serde_json::to_writer(stdout(), &v)?;
|
serde_json::to_writer(stdout(), &v)?;
|
||||||
println!("");
|
println!("");
|
||||||
|
stdout().flush()?;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Err(ref e) if e.is_corrupt_frame() => {
|
||||||
|
eprintln!("WARN: Corrupt frame, error: {:?}", e);
|
||||||
|
stderr().flush()?;
|
||||||
|
}
|
||||||
Err(framed::Error::EofBeforeFrame) => return Ok(()),
|
Err(framed::Error::EofBeforeFrame) => return Ok(()),
|
||||||
Err(e) => return Err(Error::from(e)),
|
Err(e) => return Err(Error::from(e)),
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,6 +40,21 @@ pub enum Error {
|
||||||
Ssmarshal(ssmarshal::Error),
|
Ssmarshal(ssmarshal::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
/// Returns true if the error represents a corrupted frame. Data
|
||||||
|
/// may have been lost but the decoder should decode the next
|
||||||
|
/// frame correctly.
|
||||||
|
pub fn is_corrupt_frame(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Error::ChecksumError |
|
||||||
|
Error::CobsDecodeFailed |
|
||||||
|
Error::EofDuringFrame
|
||||||
|
=> true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "use_std")]
|
#[cfg(feature = "use_std")]
|
||||||
impl From<io::Error> for Error {
|
impl From<io::Error> for Error {
|
||||||
fn from(e: io::Error) -> Error {
|
fn from(e: io::Error) -> Error {
|
||||||
|
|
Loading…
Reference in a new issue