OpenViSTAI · Agents · Blockchain · Crypto
Menu
OPENVIST RECIPES

Classify canonical dotted IPv4 text with Rust

Rust

Check decimal address spelling under an explicit rule without DNS resolution or network activity.

Rust code excerpt: Classify canonical dotted IPv4 text with Rust. Version 0.1.0. Read the full recipe for code, sources and recorded test scope.

Check decimal address spelling under an explicit rule without DNS resolution or network activity. Work only with supplied input; this does not contact external services or modify input.

Before you start

  • Save as recipe.rs and compile with Rust 1.99.0 using: rustc --edition=2021 recipe.rs -o recipe
  • Run ./recipe with input supplied through stdin. No CLI arguments are accepted, including help flags.
  • Reads at most 65537 bytes and rejects input exceeding 65536 bytes. Requires strict UTF-8, rejects a leading UTF-8 BOM, and rejects every CR byte.
  • Splits only at LF, discards exactly empty segments, and preserves all other text without trimming or normalization. Allows at most 100 nonempty lines, each at most 256 UTF-8 bytes. All validation precedes classification and successful stdout.
  • Each retained line produces one boolean in input order. True means exactly four ASCII decimal octets in 0..255, separated by dots, with no leading zeroes except the single digit 0. Signs, spaces, non-ASCII digits, and other address spellings produce false rather than input rejection.
  • Special, private, and reserved addresses are classified solely by spelling. No DNS resolution, networking, grouping, or deduplication occurs.
  • Success exits 0 and writes exactly one JSON object followed by a newline, with no stderr. Empty input or input containing only LF bytes produces {"valid":[]}.
  • Invalid arguments, invalid input, and stdin-read failures exit 2, write no stdout, and emit exactly error: invalid input followed by a newline on stderr, subject to the failure limitations below. Diagnostics never contain input values.

Build and check

  1. Save the example as recipe.rs.
  2. Compile with Rust 1.99.0 using rustc --edition=2021 recipe.rs -o recipe.
  3. Prepare UTF-8 input.txt following the documented operation-specific conventions.
  4. Run ./recipe < input.txt.
  5. Inspect the JSON result. Exit 2 with exactly error: invalid input followed by a newline on stderr and no stdout identifies rejected input or stdin-read failure. Output-write failures may also exit nonzero, without that diagnostic and potentially after partial stdout; these are outside the input-error guarantee.

Limits to understand

  • Stdin may block while waiting for EOF or enough bytes to establish that the size limit was exceeded.
  • Memory use is bounded by the input-size limit: O(65537) input storage, up to 100 borrowed line references, and at most 612 bytes of JSON output, plus allocator capacity and standard-library I/O overhead. No duplicate line strings are stored.
  • Successful output reveals the number and order of nonempty lines and their classification results; treat that information as potentially sensitive.
  • Memory-allocation failures and output-write or flush failures are outside the input-error guarantee. Output failures may leave partial output; detected stdout failures exit 2 without attempting an input-error diagnostic. Stderr failures may prevent delivery of the diagnostic.
  • Only standard-library facilities are used. The program performs no filesystem access, networking, subprocess creation, dynamic loading, or environment-variable access.
  • This checks spelling only, not routing, ownership, public reachability or address safety.

Run it

rustc --edition=2021 recipe.rs -o recipe
./recipe < input.txt

Example input

127.0.0.1
255.255.255.255
256.0.0.1

Expected output

{"valid":[true,true,false]}
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
use std::io::{self, Read, Write};

fn canonical_ipv4(text: &str) -> bool {
    let mut parts = text.split('.');
    for _ in 0..4 {
        let part = match parts.next() {
            Some(part) => part,
            None => return false,
        };
        let bytes = part.as_bytes();
        if bytes.is_empty() || bytes.len() > 3 {
            return false;
        }
        if bytes.len() > 1 && bytes[0] == b'0' {
            return false;
        }
        let mut value: u16 = 0;
        for &byte in bytes {
            if !byte.is_ascii_digit() {
                return false;
            }
            value = value * 10 + u16::from(byte - b'0');
        }
        if value > 255 {
            return false;
        }
    }
    parts.next().is_none()
}

fn prepare_output() -> Result<String, ()> {
    if std::env::args_os().skip(1).next().is_some() {
        return Err(());
    }

    let stdin = io::stdin();
    let mut reader = stdin.lock().take(65_537);
    let mut input = Vec::new();
    reader.read_to_end(&mut input).map_err(|_| ())?;
    if input.len() > 65_536 {
        return Err(());
    }

    let text = std::str::from_utf8(&input).map_err(|_| ())?;
    if text.starts_with('\u{feff}') || input.contains(&b'\r') {
        return Err(());
    }

    let mut lines = Vec::new();
    for line in text.split('\n') {
        if line.is_empty() {
            continue;
        }
        if line.len() > 256 || lines.len() >= 100 {
            return Err(());
        }
        lines.push(line);
    }

    // Every input limit has been validated before classification starts.
    let mut output = String::from("{\"valid\":[");
    for (index, line) in lines.iter().enumerate() {
        if index != 0 {
            output.push(',');
        }
        output.push_str(if canonical_ipv4(line) { "true" } else { "false" });
    }
    output.push_str("]}\n");
    Ok(output)
}

fn main() {
    match prepare_output() {
        Ok(output) => {
            let stdout = io::stdout();
            let mut writer = stdout.lock();
            if writer.write_all(output.as_bytes()).is_err() {
                std::process::exit(2);
            }
            if writer.flush().is_err() {
                std::process::exit(2);
            }
        }
        Err(()) => {
            let stderr = io::stderr();
            let mut writer = stderr.lock();
            let _ = writer.write_all(b"error: invalid input\n");
            let _ = writer.flush();
            std::process::exit(2);
        }
    }
}
What to verify after running
  • The example must produce the documented JSON result.
  • Empty stdin must produce the documented empty result.
  • Reject extra arguments, malformed UTF-8, a leading BOM, oversized input and unreadable stdin with the fixed input-error diagnostic and no stdout.

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-14.

    Six independent CLI fixtures and 17 supplementary cases are executed in pinned, offline Rust 1.99.0 containers. These checks do not establish exhaustive correctness or behavior on other versions.