devone 0.2.0

In addition to /dev/zero, aka, a UNIX virtual device, it can simulate /dev/one.
use clap::Parser;
use std::{fs::*, io::*, os::unix::fs::FileExt};
#[derive(Parser)]
struct Cli {
    #[arg(default_value_t = 1)]
    ///specify 0 or 1 to output
    val: u8,
    #[arg(default_value_t = String::new(), short, long)]
    ///input file
    r#if: String,
    #[arg(default_value_t = String::new(), short, long)]
    ///output file
    of: String,
    #[arg(default_value_t = false, short, long)]
    ///append instead of overwrite
    append: bool,
    #[arg(default_value_t = 0, short, long)]
    ///always outputing
    nonstop: u8,
}
fn main() -> Result<()> {
    let args = Cli::parse();
    let val: [u8; 1] = if args.val == 0 {
        [0b0000_0000]
    } else if args.val == 1 {
        [0b1111_1111]
    } else {
        [args.val]
    };

    let d = |mut f: File| f.flush();
    let of = || {
        let f = OpenOptions::new()
            .create(true)
            .write(true)
            .append(args.append)
            .open(&args.of)
            .unwrap();
        f
    };
    let w: Box<dyn Fn(&[u8], u64) -> Result<()>> = if args.of == String::new() {
        Box::new(|v, _| stdout().write_all(v))
    } else {
        Box::new(|v, p| {
            let f = of();
            if let Err(e) = f.write_at(v, p) {
                Err(e)
            } else {
                let mut h = Ok(());
                if let Err(e) = d(f) {
                    h = Err(e)
                }
                h
            }
        })
    };
    let w: Box<dyn Fn() -> Result<()>> = if args.r#if == String::new() {
        Box::new(|| w(&val, 0))
    } else {
        Box::new(|| {
            let f = File::open(&args.r#if)?;
            let mut b = [0u8; 1];
            let mut p = 0u64;
            loop {
                if let Ok(0) = f.read_at(&mut b, p) {
                    break Ok(());
                }
                if let Err(e) = w(&b, p) {
                    break Err(e);
                }
                p += 1
            }
        })
    };

    if args.nonstop > 0 {
        loop {
            if let Err(e) = w() {
                break Err(e);
            }
        }
    } else {
        w()
    }
}