agram 1.0.1

An offline anagram library
Documentation
#![doc = include_str!("../README.md")]

use libflate::gzip::Decoder;
use std::io::Read;

const COMPRESSED_LIST: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/word_list.gz"));

lazy_static::lazy_static! {
    /// Exposes the list of words in case you want to use it.
    pub static ref LIST: Vec<String> = {
        let mut dec = Decoder::new(COMPRESSED_LIST).expect("Failed to initialize runtime decoder");

        let mut output = Vec::new();
        dec.read_to_end(&mut output).expect("Failed to decompress list");

        std::str::from_utf8(output.as_slice()).expect("Failed to interpret decompressed data").split("\n").map(|x| x.to_string()).collect()
    };
}

/// Possible anagrams.
#[derive(Clone, Debug, PartialEq)]
pub struct Anagrams {
    /// The number of anagrams returned.
    pub count: usize,
    /// A list of valid anagrams.
    pub words: Vec<String>,
}

/// Initialize the decompression, this isn't required but it will make your first call faster.
pub fn init() {
    lazy_static::initialize(&LIST);
}

/// Get anagrams from a query.
pub fn get<A: AsRef<str>>(search: A) -> Anagrams {
    let search = search.as_ref().to_lowercase();
    let search_chars: Vec<char> = search.chars().collect();

    let mut words = Vec::new();

    'word_loop: for word in LIST.iter() {
        if word.chars().count() != search_chars.len() || word == &search {
            continue;
        }

        for char in search_chars.iter() {
            if word.matches(*char).count() != search.matches(*char).count() {
                continue 'word_loop;
            }
        }

        words.push(word.clone());
    }

    Anagrams {
        count: words.len(),
        words,
    }
}