shifter 0.1.4

A CLI tool to rotate lines from stdin by n positions
use rand::Rng;
use std::env;
use std::io::{self, BufRead, Write};

fn normalize_shift(n: isize, len: usize) -> usize {
    let len_i = len as isize;
    let mut k = n % len_i;
    if k < 0 {
        k += len_i;
    }
    k as usize
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut random = false;
    let mut shift_arg: Option<isize> = None;

    for a in env::args().skip(1) {
        match a.as_str() {
            "-r" | "--random" => random = true,
            _ => {
                if shift_arg.is_some() {
                    eprintln!("Usage: shifter [--random|-r] [shift]");
                    std::process::exit(1);
                }
                shift_arg = Some(a.parse()?);
            }
        }
    }

    let stdin = io::stdin();
    let lines: Vec<String> = stdin.lock().lines().collect::<Result<_, _>>()?;
    if lines.is_empty() {
        return Ok(());
    }

    let k = if random {
        let mut rng = rand::rng();
        rng.random_range(0..lines.len())
    } else {
        let n = shift_arg.unwrap_or(0);
        normalize_shift(n, lines.len())
    };

    let mut out = io::BufWriter::new(io::stdout());
    for s in lines[k..].iter().chain(lines[..k].iter()) {
        writeln!(out, "{}", s)?;
    }
    Ok(())
}