Skip to main content
tag command line
Link
dfhwze
  • 13.9k
  • 3
  • 38
  • 101
Source Link

Join and map command line arguments in Rust

Is there a more natural way to do this in rust? I'm having a lot of difficulty trying to make this look clean. Type mismatches and borrowing have me stumped. What are some refactors that I could make?

Input

  • Take in list of space-separated, command-line arguments

Output

  • Book (join all arguments except the last)
  • Reference (the last argument)
  • File (looked up via the book)

I abbreviated the books_to_files mapping to only include a couple examples of books with different word lengths.

Examples

In:                             Out:

Genesis 1:1                     Genesis, 1:1, mhc1.txt
Song of Solomon 2:2-4           Song of Solomon, 2:2-4, mhc3.txt
Acts of the Apostles 3:3-9      Acts of the Apostles, 3:3-9, mhc6.txt

Source Code

use std::env;
use std::collections::HashMap;

fn main() {
    let args: Vec<String> = env::args().collect();

    let book: String;
    if args.len() == 3 {
        book = args[1].clone();
    } else if args.len() == 4 {
        book = args[1].clone() + " " + &args[2].clone();
    } else if args.len() == 5 {
        book = args[1].clone() + " " + &args[2].clone() + " " + &args[3].clone();
    } else if args.len() == 6 {
        book = args[1].clone() + " " + &args[2].clone() + " " + &args[3].clone() + " " + &args[4].clone();
    } else {
        panic!("Wrong number of arguments");
    }
    let reference: String = args[args.len()-1].clone(); 
    let file: String = get_file(&book);

    println!("{}, {}, {}", book, reference, file);
}

fn get_file(book: &String) -> String {
    let books_to_files: HashMap<&str, &str> = [
        ("Genesis", "mhc1.txt"),
        ("First Samuel", "mhc2.txt"),
        ("Song of Solmon", "mhc3.txt"),
        ("Acts of the Apostles", "mhc6.txt"),
        ("First Corinthians", "mhc6.txt"),
        ("Galatians", "mhc6.txt"),
    ].iter().cloned().collect();

    books_to_files.get::<str>(&book.to_string()).unwrap().to_string()
}

```