kingslayer 0.5.5

A text adventure dungeon crawler game written in Rust
Documentation
use rayon::prelude::*;

use crate::input::CmdTokens;

#[derive(Clone, Debug)]
pub struct Lexer;

impl Lexer {
    pub fn lex(s: &str) -> CmdTokens {
        let words = Lexer::mod_words(Lexer::filter_parts(s));

        if words.is_empty() {
            CmdTokens::default()
        } else if words.len() < 2 {
            CmdTokens::new(words[0].to_owned())
        } else {
            let prep_pos = if cfg!(target_arch = "wasm32") {
                words
                    .iter()
                    .position(|r| ["in", "inside", "from", "on", "with"].contains(&r.as_str()))
            } else {
                words
                    .par_iter()
                    .position_any(|r| ["in", "inside", "from", "on", "with"].contains(&r.as_str()))
            };

            if let Some(pos) = prep_pos {
                if pos == 0 {
                    CmdTokens::new(words[0].to_owned()).with_obj(words[1..].join(" "))
                } else {
                    let obj = if words[1..pos].is_empty() {
                        None
                    } else {
                        Some(words[1..pos].join(" "))
                    };

                    let obj_prep = if words[pos + 1..].is_empty() {
                        None
                    } else {
                        Some(words[pos + 1..].join(" "))
                    };

                    CmdTokens::from(
                        Some(words[0].to_owned()),
                        obj,
                        Some(words[pos].to_owned()),
                        obj_prep,
                    )
                }
            } else {
                CmdTokens::new(words[0].to_owned()).with_obj(words[1..].join(" "))
            }
        }
    }

    fn filter_parts(s: &str) -> Vec<String> {
        if cfg!(target_arch = "wasm32") {
            s.split_whitespace()
                .map(str::to_lowercase)
                .filter(|w| {
                    !([
                        "a", "an", "around", "at", "of", "my", "that", "the", "through", "to", "'",
                    ])
                    .contains(&w.as_str())
                })
                .collect()
        } else {
            s.par_split_whitespace()
                .map(str::to_lowercase)
                .filter(|w| {
                    !([
                        "a", "an", "around", "at", "of", "my", "that", "the", "through", "to", "'",
                    ])
                    .contains(&w.as_str())
                })
                .collect()
        }
    }

    fn mod_words(mut words: Vec<String>) -> Vec<String> {
        for w in words.iter_mut() {
            match w.as_str() {
                "n" => *w = String::from("north"),
                "s" => *w = String::from("south"),
                "e" => *w = String::from("east"),
                "w" => *w = String::from("west"),
                "ne" => *w = String::from("northeast"),
                "nw" => *w = String::from("northwest"),
                "se" => *w = String::from("southeast"),
                "sw" => *w = String::from("southwest"),
                "u" => *w = String::from("up"),
                "d" => *w = String::from("down"),
                "r" => *w = String::from("again"),
                _ => (),
            }
        }
        words
    }
}