A UTF-8 byte-order mark (BOM) is optional, but some downstream text tools handle it differently. This small CLI checks only whether the input begins with the exact UTF-8 BOM bytes (`EF BB BF`) and reports the byte length. It reads the data without changing it and rejects invalid UTF-8.
Before you start
- Standard library only; no external crates, unsafe code, include macros, environment variables, subprocesses, networking, or filesystem writes.
- Accept exactly one CLI argument: a local UTF-8 file path or `-` for standard input.
- Read all bytes, reject invalid UTF-8, and report total byte count and whether the first three bytes are exactly the UTF-8 BOM.
- Write successful results to stdout and actionable failures to stderr; use a nonzero exit only on failure.
- Treat all input as untrusted text and never execute or alter it.
Build and check
- Save the Rust source as `recipe.rs`.
- Compile it with `rustc --edition=2021 recipe.rs -o recipe`.
- Create a synthetic UTF-8 input whose bytes are `EF BB BF 68 69 0A`.
- Run `./recipe sample.txt` and compare stdout with the exact expected output.
- Also try `./recipe -` with the same bytes on stdin, a file without a BOM, invalid UTF-8, a missing path, and an incorrect number of arguments; confirm failures are actionable and go to stderr.
Limits to understand
- The program reads the entire input into memory, so it is intended for reasonably sized saved text.
- It reports only whether the exact UTF-8 BOM byte sequence is at offset zero; it does not detect other encodings or BOM-like bytes elsewhere.
- A BOM is valid UTF-8 and remains part of the reported byte count.
- No execution or test results are claimed here.
What this example adds
No upstream implementation was supplied. This recipe is a focused BOM-and-byte-length audit rather than another line, whitespace, character-grouping, or line-ending summary. It uses only the Rust standard library, validates the complete byte stream as UTF-8, checks the BOM at the byte level, and keeps input read-only.
Run it
Intended runner: Rust 1.90.0, edition 2021. Compile with `rustc --edition=2021 recipe.rs -o recipe`. Run `./recipe <file>` to inspect a file, or `./recipe -` and provide text on standard input. Exactly one argument is required. Read and validation failures are written to stderr with a nonzero exit status; successful counts go to stdout.Example input
Synthetic input file bytes: `EF BB BF 68 69 0A` (UTF-8 text containing a BOM followed by `hi` and a newline).Expected output
bytes: 6
utf8_bom: yes
