~exitb/retrofit

6670c94beefb20dd6fd544ef4e365f27aca45c78 — exitb 1 year, 10 months ago 990d824
Proper error handling for all of the application
1 files changed, 31 insertions(+), 20 deletions(-)

M src/main.rs
M src/main.rs => src/main.rs +31 -20
@@ 8,7 8,7 @@ use ansi::{AnsiCode, Escape};
use clap::{App, Arg};
use cp437::Cp437;
use limit_rate::{Baud, LimitRate};
use map_result::{AndThenResult, MapErr, MapResult};
use map_result::{AndThenResult, MapErr};
use std::fs::File;
use std::io::{stdin, stdout, Read, Write};
use std::io::{BufReader, BufWriter};


@@ 26,18 26,21 @@ enum Error {
    UnableToReadBytes(std::io::Error),
    AnsiEscapeIssue(ansi::Error),
    Adapter(adapter::Error),
    WriteOut(std::io::Error),
    TerminationHandlerSetting(ctrlc::Error),
    FileOpening(std::io::Error),
}

// type Result<T> = std::result::Result<T, Error>;
type Result<T> = std::result::Result<T, Error>;

fn main() {
fn retrofit() -> Result<()> {
    let running_flag = Arc::new(AtomicBool::new(true));
    let handler_running_flag = running_flag.clone();

    ctrlc::set_handler(move || {
        handler_running_flag.store(false, Ordering::SeqCst);
    })
    .expect("Error setting Ctrl-C handler");
    .map_err(Error::TerminationHandlerSetting)?;

    let matches = App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))


@@ 105,7 108,10 @@ fn main() {
    };

    let source = match matches.value_of("FILE") {
        Some(filename) => Box::new(File::open(filename).unwrap()) as Box<dyn Read>,
        Some(filename) => {
            let file = File::open(filename).map_err(Error::FileOpening)?;
            Box::new(file) as Box<dyn Read>
        }
        None => Box::new(stdin()) as Box<dyn Read>,
    };



@@ 116,7 122,7 @@ fn main() {

    let mut output = BufWriter::new(stdout());

    let result = BufReader::new(source)
    BufReader::new(source)
        .bytes()
        .map_err(Error::UnableToReadBytes)
        .limit_rate(baud.map(Baud))


@@ 126,9 132,6 @@ fn main() {
                .escape()
                .map_err(Error::AnsiEscapeIssue)
                .and_then_result(|escaped| {
                    // escaped
                    //     .for_each(|code| println!("{:?}", code))

                    escaped
                        .take_while(|code| !matches!(code, AnsiCode::ControlCharacter('\x1A')))
                        .adapt(


@@ 140,18 143,26 @@ fn main() {
                            running_flag,
                        )
                        .map_err(Error::Adapter)
                        .map_result(|adapted| adapted.for_each(|adapted| match adapted {
                            Adapted::Code(code) => write!(output, "{}", code).unwrap(),
                            Adapted::Boundary => {
                                if flush_needed {
                                    output.flush().unwrap()
                                }
                            }
                        }))
                        .and_then_result(|mut adapted| {
                            adapted
                                .try_for_each(|adapted| match adapted {
                                    Adapted::Code(code) => write!(output, "{}", code),
                                    Adapted::Boundary => {
                                        if flush_needed {
                                            output.flush()
                                        } else {
                                            Ok(())
                                        }
                                    }
                                })
                                .map_err(Error::WriteOut)
                        })
                })
        });
        })
}

    if let Err(error) = result {
        println!("Got error: {:?}", error);
fn main() {
    if let Err(error) = retrofit() {
        eprintln!("Stopped with an error: {:?}", error);
    }
}