build.rs (4624B)
1 use std::env; 2 use std::fmt::Write as OtherWrite; 3 use std::fs::File; 4 use std::io::Read; 5 use std::io::Write; 6 use std::path::Path; 7 use std::string::String; 8 9 fn make_diceware_wordlist(array_name: String) -> impl Fn(&str) -> String { 10 move |contents: &str| { 11 // 7776 words = 6*6*6*6*6; five 6 faced dice throws. 12 format!("pub static {}: [&str; 7776] = [\n", array_name) 13 + &contents 14 .split('\n') 15 .skip(2) 16 .take(6 * 6 * 6 * 6 * 6) 17 .map(|s| s.split_once('\t').unwrap().1) 18 .map(|s| { 19 s.chars() 20 .map(|c| { 21 if c == '"' { 22 "\\\"".to_owned() 23 } else { 24 c.to_string() 25 } 26 }) 27 .collect::<String>() 28 }) 29 .fold(String::new(), |mut output, s| { 30 writeln!(output, " \"{}\",", s).unwrap(); 31 output 32 }) 33 + "];\n\n" 34 } 35 } 36 37 fn make_minilock_wordlist(contents: &str) -> std::string::String { 38 // 58110 words in the MiniLock wordlist. 39 "pub static MINILOCK_WORDLIST: [&str; 58110] = [\n".to_owned() 40 + &contents[1023..543718] 41 .split(',') 42 .fold(String::new(), |mut output, s| { 43 writeln!(output, " \"{}\",\n", s).unwrap(); 44 output 45 }) 46 + "];\n" 47 } 48 49 fn make_eff_long_wordlist(contents: &str) -> String { 50 // 7776 words = 6*6*6*6*6; five 6 faced dice throws. 51 "pub static EFF_LONG_WORDLIST: [&str; 7776] = [\n".to_owned() 52 + &contents 53 .split('\n') 54 .take(6 * 6 * 6 * 6 * 6) 55 .map(|x| x.split('\t').nth(1).unwrap()) 56 .fold(String::new(), |mut output, s| { 57 writeln!(output, " \"{}\",", s).unwrap(); 58 output 59 }) 60 + "];\n" 61 } 62 63 fn make_eff_short_wordlist(array_name: String) -> impl Fn(&str) -> String { 64 move |contents: &str| { 65 // 1296 words = 6*6*6*6; five 6 faced dice throws. 66 format!("pub static {}: [&str; 1296] = [\n", array_name) 67 + &contents 68 .split('\n') 69 .take(6 * 6 * 6 * 6) 70 .map(|x| x.split('\t').nth(1).unwrap()) 71 .fold(String::new(), |mut output, x| { 72 writeln!(output, " \"{}\",", x).unwrap(); 73 output 74 }) 75 + "];\n" 76 } 77 } 78 79 fn build_wordlist( 80 wordlist_file_path: &str, 81 destination_file: &mut File, 82 make_wordlist: &dyn Fn(&str) -> String, 83 ) { 84 let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); 85 println!("{}", manifest_dir); 86 let wordlist_file_path = Path::new(&manifest_dir).join(wordlist_file_path); 87 88 let mut wordlist_file = File::open(&wordlist_file_path).unwrap(); 89 90 let mut wordlist_string = String::new(); 91 92 wordlist_file.read_to_string(&mut wordlist_string).unwrap(); 93 94 destination_file 95 .write_all(make_wordlist(&wordlist_string).as_bytes()) 96 .unwrap(); 97 } 98 99 fn main() { 100 let out_dir = env::var("OUT_DIR").unwrap(); 101 let dest_path = Path::new(&out_dir).join("diceware.rs"); 102 let mut destination_file = File::create(&dest_path).unwrap(); 103 104 build_wordlist( 105 "wordlists/beale.wordlist.asc", 106 &mut destination_file, 107 &make_diceware_wordlist("BEALE_WORDLIST".to_string()), 108 ); 109 build_wordlist( 110 "wordlists/diceware.wordlist.asc", 111 &mut destination_file, 112 &make_diceware_wordlist("REINHOLD_WORDLIST".to_string()), 113 ); 114 build_wordlist( 115 "wordlists/phrase.js", 116 &mut destination_file, 117 &make_minilock_wordlist, 118 ); 119 build_wordlist( 120 // They call it "EFF's Long Wordlist" on https://www.eff.org/dice, not "EFF's Large 121 // Wordlist", although the file name is different, so I will call it "long" rather than 122 // "large". 123 "wordlists/www.eff.org/files/2016/07/18/eff_large_wordlist.txt", 124 &mut destination_file, 125 &make_eff_long_wordlist, 126 ); 127 build_wordlist( 128 "wordlists/www.eff.org/files/2016/09/08/eff_short_wordlist_1.txt", 129 &mut destination_file, 130 &make_eff_short_wordlist("EFF_SHORT_WORDLIST_1".to_string()), 131 ); 132 build_wordlist( 133 "wordlists/www.eff.org/files/2016/09/08/eff_short_wordlist_2_0.txt", 134 &mut destination_file, 135 &make_eff_short_wordlist("EFF_SHORT_WORDLIST_2_0".to_string()), 136 ); 137 }