use std::fs::File; use std::io::{self, BufRead}; use std::path::Path; use std::env; use std::collections::HashMap; fn main() { let args: Vec = env::args().collect(); let file_path = &args[1]; // File must exist in the current path if let Ok(lines) = read_lines(file_path) { // Consumes the iterator, returns an (Optional) String let mut redirect_map : HashMap> = HashMap::new(); let mut destinations : Vec = Vec::new(); for line in lines.flatten() { let line = String::from(line.split_at(line.find("#").unwrap_or(line.len())).0); let destination = line.split_at(line.find(char::is_whitespace).unwrap_or(0)).0; if destination == "" { continue; } let redirects: Vec = line.split_at(line.find(char::is_whitespace).unwrap_or(0)).1.split(", ") .map(|address| to_mailaddress(address)).collect(); if redirects.len() == 0 { continue; } destinations.push(to_mailaddress(destination)); redirect_map.insert(to_mailaddress(destination), redirects); } let mut changed = true; while changed { changed = false; let mut all_new_redirects : HashMap> = HashMap::new(); for destination in destinations.iter() { for forward_to in redirect_map.get(destination).unwrap().iter() { if let Some(new_redirects) = redirect_map.get(forward_to) { changed = true; all_new_redirects.entry(destination.clone()).or_insert(redirect_map.get(destination).unwrap().clone()) .retain(|dest| *dest != *forward_to); all_new_redirects.entry(destination.clone()).and_modify(|d| d.extend(new_redirects.iter().map(|x| x.clone()))); } } } for (destination, new_redirect) in all_new_redirects { *redirect_map.get_mut(&destination).unwrap() = new_redirect; } } println!("{:#?}", redirect_map); } } fn to_mailaddress(local_part: &str) -> String { let local_part = local_part.trim(); if local_part.contains("@") { return String::from(local_part); } return local_part.to_string() + "@mathebau.de"; } // The output is wrapped in a Result to allow matching on errors. // Returns an Iterator to the Reader of the lines of the file. fn read_lines

(filename: P) -> io::Result>> where P: AsRef, { let file = File::open(filename)?; Ok(io::BufReader::new(file).lines()) }