engish 0.3.9

A language utility for sampling and building words.
Documentation
use engish::language::{Adjective, Dictionary, DictionarySampling, DictionaryStack, Noun, Verb};
use rand::rng;

/// This example demonstrates how to create a `DictionaryStack`, populate it with
/// multiple dictionaries, and then sample random words from it, showcasing
/// its hierarchical sampling behavior.
fn main() {
    // 1. Create a "base" dictionary with some common words.
    let mut base_dict = Dictionary::new();
    base_dict.add_word(Noun::new_common("man"));
    base_dict.add_word(Verb::new_regular("walk"));
    println!(
        "Created a base dictionary with {} nouns and {} verbs.",
        base_dict.get_all::<Noun>().len(),
        base_dict.get_all::<Verb>().len()
    );

    // 2. Create a "specific" dictionary, for example, for a fantasy setting.
    // This dictionary will be prioritized during sampling.
    let mut fantasy_dict = Dictionary::new();
    fantasy_dict.add_word(Noun::new_proper("Gandalf"));
    fantasy_dict.add_word(Adjective::new_regular("magical"));
    println!(
        "Created a fantasy-specific dictionary with {} nouns and {} adjectives.\n",
        fantasy_dict.get_all::<Noun>().len(),
        fantasy_dict.get_all::<Adjective>().len()
    );

    // 3. Create a DictionaryStack. Words will be sampled from `fantasy_dict` first.
    // If a word type isn't found, it will fall back to `base_dict`.
    // Note: The struct is `DictionaryStack`, which was previously named `DictionarySet`.
    let dictionary_stack = DictionaryStack::from(vec![fantasy_dict.clone(), base_dict]);
    println!("--- Created DictionaryStack (fantasy > base) ---\n");

    // Get a random number generator.
    let mut rng = rng();
    println!("--- Sampling from fantasty dictionary ---");
    sample_words(fantasy_dict, &mut rng); // This will fail!
    println!("--- Sampling from dictionary set ---");
    sample_words(dictionary_stack, &mut rng); // This will work!

}

fn sample_words(dictionary: impl DictionarySampling, rng: &mut impl rand::Rng) {
    // 4. Sample words from the stack.

    // Try to sample a Noun. Since `fantasy_dict` has nouns, it will be chosen from there.
    // Because there are two nouns ("Gandalf", "orc"), it will pick one randomly.
    if let Some(noun) = dictionary.choose::<Noun>(rng) {
        println!(
            "Randomly selected noun: {} (from the dictionary)",
            noun
        );
    } else {
        println!("No nouns found in the dictionary.");
    }

    // Try to sample a Verb. `fantasy_dict` has no verbs, so it will fall back to `base_dict`.
    if let Some(verb) = dictionary.choose::<Verb>(rng) {
        println!(
            "Randomly selected verb: {} (from the dictionary)",
            verb
        );
    } else {
        println!("No verbs found in the dictionary.");
    }

    // Try to sample an Adjective. Only `fantasy_dict` has adjectives.
    if let Some(adjective) = dictionary.choose::<Adjective>(rng) {
        println!(
            "Randomly selected adjective: {} (from the dictionary)",
            adjective
        );
    } else {
        println!("No adjectives found in the dictionary.");
    }
}