wordlists 0.2.0

Take bits, give words.
Documentation
use crate::SingleListIndexingWordlist;
use lazy_static::lazy_static;

/// The Raw list of words in the S/KEY OTP Wordlist.
pub const SKEYOTP_WORDLIST: [&'static str; 2048] =
    include!("../../static/wordlists/skeyotp/converted/wordlist.json");

lazy_static! {
    /// This is the S/KEY OTP Wordlist encoded as an Indexing wordlist.
    pub static ref SKEYOTP: SingleListIndexingWordlist = {
        let boxed = Box::new(SKEYOTP_WORDLIST);
        SingleListIndexingWordlist::new("S/KEY OTP Wordlist".to_string(), boxed)
    };
}

#[cfg(test)]
mod test {
    use super::{SKEYOTP, SKEYOTP_WORDLIST};
    use crate::bits::pack_indexes;
    use crate::{Result, Wordlist, WordlistByteConverter};

    #[test]
    fn validate_list_complete() {
        assert_eq!(2048, SKEYOTP_WORDLIST.len());
        SKEYOTP_WORDLIST.iter().for_each(|v| assert!(!v.is_empty()));
    }

    #[test]
    fn validate_bit_width() {
        assert_eq!(11, SKEYOTP.index_bit_width().unwrap());
    }

    #[test]
    fn validate_convert() -> Result<()> {
        let width = SKEYOTP.index_bit_width()?;
        let matches = vec![
            (vec![0, 0, 0, 0, 0, 0], vec!["A", "A", "A", "A", "A", "A"]),
            (
                vec![0, 1, 10, 100, 1000, 2047],
                vec!["A", "ABE", "AIR", "CUP", "FAIL", "YOKE"],
            ),
        ];
        for (indexes, words) in matches {
            let bitvec = pack_indexes(indexes, width)?;

            assert_eq!(bitvec, SKEYOTP.to_bytes(&words)?);
            assert_eq!(words, SKEYOTP.to_words(&bitvec)?);
        }
        Ok(())
    }
}