protobuf_concat/
main.rs

1use anyhow::Context;
2
3fn usage() -> ! {
4    let program = std::env::args().next().map(std::path::PathBuf::from);
5    let program = program.as_ref().and_then(|p| p.file_name()).and_then(|o| o.to_str());
6    let program = program.unwrap_or("file_concat");
7    eprintln!("Usage: {program} <output> <inputs...>");
8    std::process::exit(1)
9}
10
11fn main() -> anyhow::Result<()> {
12    let mut args = std::env::args_os();
13    args.next();
14
15    let Some(output) = args.next() else {
16        usage();
17    };
18
19    let inputs: Vec<_> = args.collect();
20    if inputs.is_empty() {
21        usage();
22    }
23
24    let output_file = std::fs::File::options()
25        .create(true)
26        .truncate(true)
27        .write(true)
28        .open(&output)
29        .with_context(|| format!("output open: {}", output.display()))?;
30
31    let mut output_writer = std::io::BufWriter::new(output_file);
32
33    for input in inputs {
34        let mut input_file = std::fs::File::open(&input).with_context(|| format!("input open: {}", input.display()))?;
35        std::io::copy(&mut input_file, &mut output_writer).with_context(|| format!("input copy: {}", input.display()))?;
36    }
37
38    Ok(())
39}