OpenViSTAI · Agents · Blockchain · Crypto
Menu
OPENVIST RECIPES

Summarize Saved Text by Final-Character Group

Rust

Read one UTF-8 text file or standard input and report how many nonblank lines end with each Unicode character, using case-sensitive, exact grouping. Ignore leading and trailing whitespace when determining each line’s final character; do not modify or execute the input.

Rust code excerpt: Summarize Saved Text by Final-Character Group. Version 0.1.0. Read the full recipe for code, sources and recorded test scope.

This Rust 2021 command-line recipe reads a saved text file, or standard input when given `-`, and groups nonblank lines by their last non-whitespace Unicode scalar value. It prints the total number of nonblank lines and the count for each ending character in sorted order. Input is treated only as read-only text.

Before you start

  • Intended runner: Rust 1.90.0, edition 2021; this is not a claim about the minimum supported Rust version.
  • Standard library only; no external crates, unsafe code, include macros, environment-variable access, threads, networking, subprocesses, or filesystem writes.
  • Accept exactly one CLI argument: a UTF-8 file path or `-` for standard input.
  • Treat all input as untrusted, read-only UTF-8 text; propagate I/O and decoding failures instead of silently truncating input.
  • Count a line as nonblank when its Unicode-whitespace-trimmed content is nonempty; use its last remaining Unicode scalar value as the grouping key.
  • Write counts and character groups to stdout, and actionable errors to stderr. Exit nonzero only for actionable failures.

Build and check

  1. Create `recipe.rs` and place the complete Rust program from the example code in it.
  2. Compile using `rustc --edition=2021 recipe.rs -o recipe`.
  3. Run `./recipe -` and enter the example text followed by end-of-file, or save equivalent UTF-8 text and run `./recipe path/to/file.txt`.
  4. Check that grouping ignores surrounding whitespace, preserves character case, and prints character groups in sorted order.
  5. Try a nonexistent path and confirm that the program prints a useful error to stderr and exits nonzero.

Limits to understand

  • Counts are held in `usize`; the program is intended for ordinary saved-text inspection, not guaranteed to handle inputs exceeding available memory or runtime limits.
  • `BufRead::lines` removes line terminators and reports invalid UTF-8 or read errors; a failure stops processing rather than producing partial success output.
  • Each line is grouped by its final non-whitespace Unicode scalar value, not by grapheme cluster; a visible character composed of multiple scalar values may therefore be grouped by its final scalar.
  • A line containing only Unicode whitespace is excluded.
  • Character labels use Rust char::escape_default: non-ASCII scalar values are printed as hexadecimal Unicode escapes such as \u{f1}; ordering follows scalar values.
  • The recorded five-case execution did not test malformed UTF-8 bytes or multiple CLI arguments. Those checks are additional manual instructions, not executed coverage claims.

What this example adds

This task is distinct from the existing first-character grouping recipe: it groups by the final non-whitespace character instead. It also differs from line-length and word-length histograms, which aggregate numeric lengths rather than characters. No upstream implementation was supplied; the design uses the standard library’s buffered line reading and an ordered map for deterministic output.

Run it

Compile with `rustc --edition=2021 recipe.rs -o recipe`. Run `./recipe <UTF-8-file>` to read a file or `./recipe -` to read standard input. Provide exactly one argument. The program does not interpret input as instructions or write to files.

Example input

Input supplied on standard input using `./recipe -`:

Apple
pear!
  tea  

Expected output

nonblank_lines: 3
!: 1
a: 1
e: 1
INSPECT THE SCRIPT

Inspect, copy and run the documented checks.

This browser preview builds code locally. It does not contact an API or run the code.

Default example ready.

Rust example
// SPDX-License-Identifier: MIT
// Copyright (c) 2026 OpenViST contributors
use std::collections::BTreeMap;
use std::env;
use std::fs::File;
use std::io::{self, BufRead, BufReader};
use std::process;

fn run() -> Result<(), String> {
    let args: Vec<String> = env::args().skip(1).collect();
    if args.len() != 1 {
        return Err("Usage: recipe <UTF-8-file|->".to_string());
    }

    let reader: Box<dyn BufRead> = if args[0] == "-" {
        Box::new(BufReader::new(io::stdin().lock()))
    } else {
        let file = File::open(&args[0])
            .map_err(|e| format!("cannot open '{}': {e}", args[0]))?;
        Box::new(BufReader::new(file))
    };

    let mut counts: BTreeMap<char, usize> = BTreeMap::new();
    let mut total = 0usize;
    for (index, result) in reader.lines().enumerate() {
        let line = result.map_err(|e| format!("cannot read line {} as UTF-8: {e}", index + 1))?;
        if let Some(ch) = line.trim().chars().last() {
            total += 1;
            *counts.entry(ch).or_insert(0) += 1;
        }
    }

    println!("nonblank_lines: {total}");
    for (ch, count) in counts {
        println!("{}: {count}", ch.escape_default());
    }
    Ok(())
}

fn main() {
    if let Err(message) = run() {
        eprintln!("error: {message}");
        process::exit(2);
    }
}
What to verify after running
  • Compile with `rustc --edition=2021 recipe.rs -o recipe`.
  • Pipe the synthetic example input to `./recipe -` and compare stdout exactly with the expected output.
  • Try input containing uppercase and lowercase final characters and verify they form separate groups.
  • Try an all-whitespace input and verify the output is `nonblank_lines: 0` with no character-group lines.
  • Try a file with invalid UTF-8 and verify the error is reported on stderr and processing fails.
  • Try invoking the program with no arguments or multiple arguments and verify the usage error is actionable.

Request or format preview

Illustrative preview. No provider response, price or balance is fetched.

Change a setting to inspect the preview.

Official sources and related profiles

    Code license: MIT. Keep the license notice with your copy.

    Example version 0.1.0 · Documentation reviewed 2026-10-12.

    Executed 5 synthetic local fixture cases in isolated Rust 1.90.0 on GitHub Actions, without network access. Declared exit codes, output assertions and input integrity checks passed. Live services, installed third-party packages and production behavior remain outside scope. Editorial approval is still required.