~kmaasrud/mvm

b07f79eadc948e1060a55a8eaebb3d042094b5a6 — Knut Magnus Aasrud 7 months ago
initial commit
6 files changed, 94 insertions(+), 0 deletions(-)

A Makefile
A README
A src/args.rs
A src/help.txt
A src/main.rs
A src/test.rs
A  => Makefile +22 -0
@@ 1,22 @@
EXE := mvm
VERSION := 0.1.0

SRC_DIR := src
SRC := $(wildcard $(SRC_DIR)/*)

RUSTC := rustc
RUSTCFLAGS = -C opt-level=3 \
			 -C target-cpu=native \
			 -C lto=thin \
			 -C codegen-units=1 \
			 -C panic=abort \
			 -C strip=symbols

all: $(EXE)

$(EXE): $(SRC)
	EXE=$(EXE) VERSION=$(VERSION) $(RUSTC) $(SRC_DIR)/main.rs -o $@ --edition=2021 $(RUSTCFLAGS)

.PHONY: clean
clean:
	rm -f $(EXE)

A  => README +0 -0
A  => src/args.rs +23 -0
@@ 1,23 @@
use std::env::args_os;
use std::ffi::OsString;
use std::process::exit;

pub fn parse_args() -> impl Iterator<Item = OsString> {
    args_os()
        .skip(1)
        .map(|arg| match arg.to_string_lossy().as_ref() {
            "-h" | "--help" => {
                eprint!("{}", include_str!("./help.txt"));
                exit(0);
            }
            "-v" | "--version" => {
                eprintln!("{} v{}", env!("EXE"), env!("VERSION"));
                exit(0);
            }
            file if !file.starts_with('-') => arg,
            flag => {
                eprint!("unknown flag: {}\n\n{}", flag, include_str!("./help.txt"));
                exit(1)
            }
        })
}

A  => src/help.txt +8 -0
@@ 1,8 @@
usage: mvm [paths...]

arguments:
    paths           the paths to move

options:
    -h --help       show the help text
    -v --version    show the version number

A  => src/main.rs +41 -0
@@ 1,41 @@
mod args;

use args::parse_args;
use std::env;
use std::error::Error;
use std::fs::{remove_file, rename, File};
use std::io::{BufRead, BufReader, Write};
use std::path::PathBuf;
use std::process::{exit, Command};

const TEMP_FILE: &str = "/tmp/mvm";

fn main() -> Result<(), Box<dyn Error>> {
    let args: Vec<PathBuf> = parse_args()
        .map(|arg| {
            let path = PathBuf::from(&arg);
            if !path.exists() {
                eprintln!("file not found: {}", path.display());
                exit(1);
            }
            path
        })
        .collect();

    let mut f = File::create(TEMP_FILE)?;
    args.iter()
        .try_for_each(|path| writeln!(f, "{}", path.display()))?;

    let editor = env::var("EDITOR").unwrap_or("nano".to_string());
    Command::new(editor).arg(TEMP_FILE).spawn()?.wait()?;

    let f = BufReader::new(File::open(TEMP_FILE)?);

    args.iter()
        .zip(f.lines().filter_map(|l| l.ok()))
        .try_for_each(|(old, new)| rename(old, new))?;

    remove_file(TEMP_FILE)?;

    Ok(())
}

A  => src/test.rs +0 -0