lich 0.2.0

Minimal password management.
Documentation
use ring::rand::{SystemRandom, SecureRandom};
use error::Error;

pub fn pwgen(
    length: usize,
    chars: &[&str]
) -> Result<String, Error> {
    if chars.len() > 256 {
        return Err(Error::AlphabetTooLarge);
    }

    if chars.len() == 0 {
        return Err(Error::EmptyAlphabet);
    }

    let mut result = String::with_capacity(length);
    let mut bytes = vec![0; length];
    let mut complete = 0;

    // The largest multiple of `chars.len()` <= 256.
    // This is necessary to maintain uniformity.
    let bound = 256 - (256 % chars.len());

    while complete < length {
        if SystemRandom.fill(&mut bytes).is_err() {
            return Err(Error::RngError);
        }

        for &byte in &bytes {
            let byte = byte as usize;
            if byte < bound {
                result.push_str(chars[byte % chars.len()]);

                complete += 1;
                if complete == length {
                    return Ok(result);
                }
            }
        }
    }

    Ok(result)
}