Conflate multiple alias input files
This commit is contained in:
parent
c28ab701f5
commit
5f324ac2a4
1 changed files with 48 additions and 23 deletions
53
src/main.rs
53
src/main.rs
|
@ -1,17 +1,30 @@
|
||||||
use std::io::{self};
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{self, BufRead};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct AliasFile {
|
||||||
|
content: io::Lines<io::BufReader<File>>,
|
||||||
|
default_domain: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() < 2 {
|
if args.len() < 2 || args.len() % 2 == 0{
|
||||||
print_help();
|
print_help();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let mut alias_files : Vec<AliasFile> = Vec::new();
|
||||||
|
for i in (1..args.len()).step_by(2) {
|
||||||
|
if let Ok(lines) = read_lines(&args[i]) {
|
||||||
|
alias_files.push(AliasFile{content: lines, default_domain: args[i+1].to_string()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let default_domain = &args[1];
|
let redirects = parse_alias_to_map(alias_files);
|
||||||
|
|
||||||
let redirects = parse_alias_to_map(default_domain);
|
|
||||||
let sieve_script = generate_sieve_script(redirects);
|
let sieve_script = generate_sieve_script(redirects);
|
||||||
println!("{}", sieve_script);
|
println!("{}", sieve_script);
|
||||||
}
|
}
|
||||||
|
@ -34,11 +47,12 @@ fn generate_sieve_script(redirects: BTreeMap<String, Vec<String>>) -> String {
|
||||||
script
|
script
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_alias_to_map(default_domain : &str) -> BTreeMap<String, Vec<String>> {
|
fn parse_alias_to_map(alias_files: Vec<AliasFile>) -> BTreeMap<String, Vec<String>> {
|
||||||
// File must exist in the current path
|
// File must exist in the current path
|
||||||
let mut redirect_map : BTreeMap<String, Vec<String>> = BTreeMap::new();
|
let mut redirect_map : BTreeMap<String, Vec<String>> = BTreeMap::new();
|
||||||
let mut destinations : Vec<String> = Vec::new();
|
let mut destinations : Vec<String> = Vec::new();
|
||||||
for line in io::stdin().lines() {
|
for alias_file in alias_files.into_iter() {
|
||||||
|
for line in alias_file.content {
|
||||||
let line = line.unwrap();
|
let line = line.unwrap();
|
||||||
let line = String::from(line.split_at(line.find("#").unwrap_or(line.len())).0);
|
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;
|
let destination = line.split_at(line.find(char::is_whitespace).unwrap_or(0)).0;
|
||||||
|
@ -46,12 +60,13 @@ fn parse_alias_to_map(default_domain : &str) -> BTreeMap<String, Vec<String>> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let redirects: Vec<String> = line.split_at(line.find(char::is_whitespace).unwrap_or(0)).1.split(" ")
|
let redirects: Vec<String> = line.split_at(line.find(char::is_whitespace).unwrap_or(0)).1.split(" ")
|
||||||
.filter(|address| address.trim().to_string().replace(",","") != "").map(|addr| to_mailaddress(addr, default_domain)).collect();
|
.filter(|address| address.trim().to_string().replace(",","") != "").map(|addr| to_mailaddress(addr, &alias_file.default_domain)).collect();
|
||||||
if redirects.is_empty() {
|
if redirects.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
destinations.push(to_mailaddress(destination, default_domain));
|
destinations.push(to_mailaddress(destination, &alias_file.default_domain));
|
||||||
redirect_map.insert(to_mailaddress(destination, default_domain), redirects);
|
redirect_map.insert(to_mailaddress(destination, &alias_file.default_domain), redirects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let mut changed = true;
|
let mut changed = true;
|
||||||
while changed {
|
while changed {
|
||||||
|
@ -74,7 +89,7 @@ fn parse_alias_to_map(default_domain : &str) -> BTreeMap<String, Vec<String>> {
|
||||||
redirect_map
|
redirect_map
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_mailaddress(local_part: &str, default_domain : &str) -> String {
|
fn to_mailaddress(local_part: &str, default_domain : &String) -> String {
|
||||||
let mut addr = local_part.trim().to_string();
|
let mut addr = local_part.trim().to_string();
|
||||||
addr = addr.replace(",", "");
|
addr = addr.replace(",", "");
|
||||||
if addr.contains("@") {
|
if addr.contains("@") {
|
||||||
|
@ -83,7 +98,17 @@ fn to_mailaddress(local_part: &str, default_domain : &str) -> String {
|
||||||
addr + "@" + default_domain
|
addr + "@" + default_domain
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_help(){
|
|
||||||
print!("Reads a virtual alias file from STDIN and needs a default domain to append to local paths, e.g.
|
// The output is wrapped in a Result to allow matching on errors.
|
||||||
cat virt_aliases | ./alias_to_sieve example.com");
|
// 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())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn print_help(){
|
||||||
|
print!("Reads a virtual alias file and needs a default domain to append to local paths, e.g.
|
||||||
|
./alias_to_sieve example.com.txt example.com ");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue