Repository: BLAKE3-team/BLAKE3
File: b3sum/src/main.rs (Rust)

Code before:
    let raw_output = args.is_present(RAW_ARG);
    let mut did_error = false;

    if let Some(files) = args.values_of_os(FILE_ARG) {
        if raw_output && files.len() > 1 {
            did_error = true;
            eprintln!("b3sum: Only one filename can be provided when using --raw");
        } else {
            for filepath in files {
                let filepath_str = filepath.to_string_lossy();
                match hash_file(&base_hasher, filepath) {
                    Ok(output) => {
                        if raw_output {
                            write_raw_output(output, len)?;
                        } else {
                            write_hex_output(output, len)?;
                            if print_names {
                                println!("  {}", filepath_str);
                            } else {
                                println!();
                            }
                        }
                    }
                    Err(e) => {
                        did_error = true;
                        eprintln!("b3sum: {}: {}", filepath_str, e);
                    }
                }
            }
        }
    } else {
        let stdin = std::io::stdin();
        let stdin = stdin.lock();
        let output = hash_reader(&base_hasher, stdin)?;
        if raw_output {
            write_raw_output(output, len)?;
        } else {
            write_hex_output(output, len)?;
            println!();
        }
    }
    std::process::exit(if did_error { 1 } else { 0 });
}


Review comment (bug):
I'm a little skeptical of this change. A common case where you hit an error here is when you do something like `b3sum *`, when the current directory also contains subdirectories. You'll see something like this:

```
$ b3sum *
af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262  a
b3sum: b: Is a directory (os error 21)
af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262  c
```

I'd expect all that output to stick together if I e.g. redirected to a file with `b3sum * > out.txt`. But with this change, only the successes would go to the file, and the errors would stay in the terminal. That seems kind of weird to me. What do you think?

Code after:
        if raw_output && files.len() > 1 {
            bail!("b3sum: Only one filename can be provided when using --raw");
        }
        for filepath in files {
            let filepath_str = filepath.to_string_lossy();
            match hash_file(&base_hasher, filepath) {
                Ok(output) => {
                    if raw_output {
                        write_raw_output(output, len)?;
                    } else {
                        write_hex_output(output, len)?;
                        if print_names {
                            println!("  {}", filepath_str);
                        } else {
                            println!();
                        }
                    }
                }
                Err(e) => {
                    did_error = true;
                    eprintln!("b3sum: {}: {}", filepath_str, e);
                }
            }
        }
    } else {
        let stdin = std::io::stdin();
        let stdin = stdin.lock();
        let output = hash_reader(&base_hasher, stdin)?;
        if raw_output {
            write_raw_output(output, len)?;
        } else {
            write_hex_output(output, len)?;
            println!();
        }
    }
    std::process::exit(if did_error { 1 } else { 0 });
}