dd-lib 0.1.0

library functions for a clone of the unix coreutil dd
Documentation
//! # 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

pub mod io;
/// configuration and parsing
pub mod opts;
/// structs and enum for success and failure
pub mod results;

use io::{conv::Converter, read::Reader, write::Writer};
use opts::{Mode, Opts};
use results::{Result, Success};

#[cfg(test)]
extern crate tempfile;
#[macro_use]
extern crate bitflags;
extern crate encoding8;

#[cfg(test)]
/// integration tests for `dd`;
mod tests;


/// The dd utility copies the standard input to the standard output.  Input data
/// is read and written in n-byte blocks (default `512`).  If input reads are
/// short, input from multiple reads are aggregated to form the output block.
/// When finished, dd displays the number of complete and partial input and
/// output blocks and truncated input records to the standard error output.
pub fn dd<E>(o: &Opts, err: E) -> Result<Success>
where
    E: std::io::Write, // in practice, this is always stderr
{
    let (stdin, stdout) = (std::io::stdin(), std::io::stdout());
    let r = Reader::new(&stdin, &o)?;
    let mut w = Writer::from_opts(&stdout, &o)?;
    let c = Converter::new(&o)?;
    let mut err = if o.status == opts::StatusLevel::Progress {
        Some(err)
    } else {
        None
    };

    match o.mode {
        Mode::Block(n) => io::copy::block(r, &mut w, c, &mut err, n),
        Mode::Unblock(n) => io::copy::unblock(r, &mut w, c, &mut err, n),
        Mode::Standard => io::copy::standard(r, &mut w, c, &mut err),
    }
}