extern crate clap; use clap::{App, Arg}; use rand::prelude::*; use std::collections::HashMap; use std::fs; fn my_gift_to(players: &mut Vec) -> Option<&String> { let mut rng = rand::thread_rng(); players.shuffle(&mut rng); Some(&players[0]) } fn main() { let matches = App::new("rsanta") .version("0.1.0") .author("Santo Cariotti ") .about("Make secret santa with your friends") .arg( Arg::with_name("file") .short("f") .long("file") .value_name("FILE") .help("Input file for players") .takes_value(true), ) .get_matches(); let config_file = matches .value_of("file") .expect("You must specify a config file"); let contents = fs::read_to_string(config_file) .expect("Error occurs reading this file") .to_string(); let mut members_data: Vec<&str> = contents.split("\n").collect(); // ignore the last element, cause it's empty members_data.pop(); let mut rng = rand::thread_rng(); members_data.shuffle(&mut rng); let mut members = HashMap::new(); for member in members_data { let details: Vec<&str> = member.split(" ").collect(); // : members.insert(details[1], details[0]); } let mut done: Vec = Vec::new(); let mut emails: Vec = Vec::new(); for (email, _) in &members { emails.push(email.to_string()); } println!("{:?}", emails); for (email, name) in members.into_iter() { loop { match my_gift_to(&mut emails) { Some(gift_to) => { if gift_to.to_string() != email.to_string() && !done.iter().any(|v| v == gift_to) { println!("{} {}", email, gift_to); done.push(gift_to.to_string()); break; } } None => break, } } } }