First rough parsing of alias file to hashmap
This commit is contained in:
parent
709cf20fa8
commit
184d8c543e
4 changed files with 90 additions and 0 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -25,3 +25,7 @@ testdata/mathebau.aliases
|
|||
|
||||
# might contain private mailadresses as well
|
||||
testdata/virt_aliases
|
||||
|
||||
|
||||
# Added by cargo
|
||||
/target
|
||||
|
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "alias_to_sieve"
|
||||
version = "0.1.0"
|
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "alias_to_sieve"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[[bin]]
|
||||
name = "alias_to_sieve"
|
||||
path = "main.rs"
|
69
main.rs
Normal file
69
main.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
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<String> = 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<String, Vec<String>> = HashMap::new();
|
||||
let mut destinations : Vec<String> = 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<String> = 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<String, Vec<String>> = 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<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
|
||||
where P: AsRef<Path>, {
|
||||
let file = File::open(filename)?;
|
||||
Ok(io::BufReader::new(file).lines())
|
||||
}
|
Loading…
Reference in a new issue