use rand::rngs::OsRng; use rand::seq::IteratorRandom; use rand::seq::SliceRandom; use std::iter::FromIterator; pub fn generate(spec: &str) { let (len, rest) = { let mut separated = spec.splitn(2, ','); let len = separated.next().unwrap(); let rest = separated.next().unwrap(); (len, rest) }; let mut rnd = OsRng::new().unwrap(); let mut password_vec: Vec = rest .chars() .cycle() .map(|c| match c { 'a' => "abcdefghijklmnopqrstuvwxyz" .chars() .choose(&mut rnd) .expect("Could not get random element"), 'A' => "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .chars() .choose(&mut rnd) .expect("Could not get random element"), '1' => "1234567890" .chars() .choose(&mut rnd) .expect("Could not get random element"), '.' => ".,/?-=#%^" .chars() .choose(&mut rnd) .expect("Could not get random element"), _ => panic!("Unknown character spec: {}", c), }) .take(len.parse().unwrap()) .collect(); password_vec.shuffle(&mut rnd); let shuffled: String = String::from_iter(password_vec.into_iter()); println!("{}", shuffled); }