1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//!
//! concatenate files that are plain, gzip, xz and zstd.
//!
//! ```text
//! Usage:
//!   aki-xcat [options] [<file>...]
//!
//! this is like a cat, zcat, xzcat, zstdcat and lz4cat.
//! with no <file> or when <file> is -, read standard input.
//! automatic discovery file type: plain, gz, xz, zst and lz4.
//!
//! Options:
//!   -p, --pipe-in <num>   read from pipe <num> [unimplemented]
//!
//!   -H, --help        display this help and exit
//!   -V, --version     display version information and exit
//!
//! Argument:
//!   <file>         utf-8 encoded text file. A compressed file of it by gzip, xz, zstd, lz4.
//!
//! Examples:
//!   You can simple use. Just arrange the files.
//!     aki-xcat file1 file2.gz file3.xz file4.zst file5.lz4
//! ```
//!
//! # Examples
//!
//! ### Command line example 1
//!
//! concatenate plain text file.
//! ```text
//! cat fixtures/plain.txt
//! ```
//! result output :
//! ```text
//! abcdefg
//! hijklmn
//! ```
//!
//! concatenate gzip text file.
//! ```text
//! zcat fixtures/gztext.txt.gz
//! ```
//! result output :
//! ```text
//! ABCDEFG
//! HIJKLMN
//! ```
//!
//! concatenate plain text file and gzip text file.
//! ```text
//! aki-xcat fixtures/plain.txt fixtures/gztext.txt.gz
//! ```
//! result output :
//! ```text
//! abcdefg
//! hijklmn
//! ABCDEFG
//! HIJKLMN
//! ```
//!
//! ### Command line example 2
//!
//! concatenate plain text file, gzip text file, xz text file, zstd text file and lz4 text file.
//! ```text
//! aki-xcat fixtures/plain.txt fixtures/gztext.txt.gz fixtures/xztext.txt.xz  fixtures/zstext.txt.zst fixtures/lz4text.txt.lz4
//! ```
//!
//! ### Library example
//!
//! See [`fn execute()`] for this library examples.
//!
//! [`fn execute()`]: crate::execute
//!

#[macro_use]
extern crate anyhow;

mod conf;
mod run;
mod util;

use flood_tide::HelpVersion;
use runnel::*;
use std::io::Write;

const TRY_HELP_MSG: &str = "Try --help for help.";

///
/// execute xcat
///
/// params:
///   - sioe: stream in/out/err
///   - program: program name. etc. "xcat"
///   - args: parameter arguments.
///
/// return:
///   - ok: ()
///   - err: anyhow
///
/// example:
///
/// ```
/// use runnel::RunnelIoeBuilder;
///
/// let r = libaki_xcat::execute(&RunnelIoeBuilder::new().build(),
///     "xcat", &["file1", "file2.gz", "file3.xz", "file4.zst"]);
/// ```
///
pub fn execute(sioe: &RunnelIoe, prog_name: &str, args: &[&str]) -> anyhow::Result<()> {
    let conf = match conf::parse_cmdopts(prog_name, args) {
        Ok(conf) => conf,
        Err(errs) => {
            for err in errs.iter().take(1) {
                if err.is_help() || err.is_version() {
                    let _r = sioe.pout().lock().write_fmt(format_args!("{}\n", err));
                    return Ok(());
                }
            }
            return Err(anyhow!("{}\n{}", errs, TRY_HELP_MSG));
        }
    };
    run::run(sioe, &conf)
}