dd 0.4.0

a clone of the unix coreutil dd
//! # dd: convert and copy a file  
//!
//! ## SYNOPSIS         
//! dd \[OPERAND\]...
//! dd OPTION
//! ## DESCRIPTION         
//! Copy a file converting and formatting according to the operands.
//! ## [`opts`]
//!
//! - **bs**=BYTES: read and write up to BYTES bytes at a time (default: 512).
//!   - **overrides ibs and obs**
//!
//! - **cbs**=BYTES: convert BYTES bytes at a time
//!
//! - **conv**=[`CONVS`][opts::flags::Conv]: convert the file as per the coma
//!   separated symbol list
//!
//! - **count**=N: copy only N input blocks
//!
//! - **ibs**=BYTES: read up to BYTES bytes at a time (default: 512)
//!
//! - **if**=FILE: read from FILE instead of stdin
//!
//! - **iflag**=[`FLAGS`][opts::flags::In]: read as per the comma separated
//!   symbol list
//!
//! - **obs**=BYTES: write BYTES bytes at a time (default: 512)
//!
//! - **of**=FILE: write to FILE instead of stdout
//!
//! - **oflag**=[`FLAGS`][opts::flags::Out]: write as per the comma separated
//!   symbol list
//!
//! - **seek**=N: skip N obs-sized blocks at start of output
//!
//! - **skip**=N: skip N ibs-sized blocks at start of input
//!
//! - **status=[LEVEL][opts::StatusLevel]**: the level of information to print
//!   to stderr
//!
//!    none: suppresses everything but error messages,
//!    progress //! - **shows** periodic transfer statistics
//!    noxfer: suppresses the final transfer statistics,
//!
//!
//! ### [Units][opts::number::units]:
//! N and BYTES may be followed by the following multiplicative suffixes:
//! - **B** = 1
//! - **K** = 1024
//! - **M**: K*K = 1024²
//! - **G**: M*K = 1024³
//! - **T**:  G*K = 1024⁴
//! - **P**: T*K = 1024⁵
//! - **Z**: P*K = 1024⁶
//! - **KB**: 10⁶
//! - **MB**: 10⁹
//! - **GB**: 10¹²
//! - **TB**: 10¹⁵
//! - **ZB**: 10¹⁸

//! ### [`CONV`][opts::flags::Conv]
//! Each CONV symbol may be:

//! 
//! - **ascii**  from EBCDIC to ASCII

//! 
//! - **ebcdic** from ASCII to EBCDIC

//! 
//! - **ibm**    from ASCII to alternate EBCDIC

//! 
//! - **block**  pad newline-terminated records with spaces to cbs-size

//! 
//! - **unblock** replace trailing spaces in cbs-size records with newline

//! 
//! - **lcase**  change upper case to lower case

//! 
//! - **ucase**  change lower case to upper case

//! 
//! - **sparse** try to seek rather than write the output for NUL input blocks

//! 
//! - **swab**   swap every pair of input bytes

//! 
//! - **sync**   pad every input block with NULs to ibs-size; when used with
//!   block or unblock, pad with spaces rather than NULs

//! 
//! - **excl**   fail if the output file already exists

//! 
//! - **nocreat** do not create the output file

//! 
//! - **notrunc** do not truncate the output file

//! 
//! - **noerror** continue after read errors

//! 
//! - **fdatasync**
//! physically write output file data before finishing
//! - **fsync**  likewise, but also write metadata

//! ### SIGNALS
//! Sending a USR1 signal to a running 'dd' process makes it print I/O
//! statistics to standard error and then resume copying.
//!
//!
//! ### OPTIONS
//! --help display this help and exit
//! --version
//! output version information and exit
//! ### AUTHOR         
//! Originally Written by Paul Rubin, David MacKenzie, and Stuart Kemp.
//! Clone written _only_ by looking at man page by Efron Licht
//! input, output, and encoding

extern crate dd_lib;
fn main() {

    match dd_lib::opts::Opts::new(std::env::args()) {
        Ok(opts) => match dd_lib::dd(&opts) {
            Ok(success) => exit_ok(success),
            Err(err) => exit_err(err),
        },
        Err(err) => exit_err(err),
    }
}

fn exit_err<E: std::fmt::Display>(err: E) -> ! {
    eprintln!("{}", err);
    std::process::exit(1)
}

fn exit_ok<S: std::fmt::Display>(success: S) -> ! {
    println!("{}", success);
    std::process::exit(0)
}