hco 0.0.0-1

LIB: Math and container utilities for Rust. Notice: study purpose, not production ready.
Documentation
use serde::Deserialize;
use std::collections::HashMap;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Tense {
    Present,
    Past,
    Future,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Aspect {
    Simple,
    Progressive,
    Completed,
}

#[derive(Clone, Debug, Deserialize)]
pub struct NounKeyData {
    pub key: String,
    pub category: String,
}

#[derive(Clone, Debug, Deserialize)]
pub struct VerbKeyData {
    pub key: String,
    pub category: String,
    pub pattern: VerbPattern,
}

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum VerbPattern {
    Intransitive,
    Transitive,
    Ditransitive,
}

#[derive(Clone, Debug)]
pub enum Modifier {
    Location(String),
    Time(String),
    Manner(String),
}

#[derive(Clone, Debug)]
pub struct Clause {
    pub subject: String,
    pub verb: String,
    pub object: Option<String>,
    pub recipient: Option<String>,
    pub modifiers: Vec<Modifier>,
    pub tense: Tense,
    pub aspect: Aspect,
    pub negative: bool,
}

impl Clause {
    pub fn new(subject: impl Into<String>, verb: impl Into<String>) -> Self {
        Self {
            subject: subject.into(),
            verb: verb.into(),
            object: None,
            recipient: None,
            modifiers: Vec::new(),
            tense: Tense::Present,
            aspect: Aspect::Simple,
            negative: false,
        }
    }

    pub fn object(mut self, object: impl Into<String>) -> Self {
        self.object = Some(object.into());
        self
    }

    pub fn recipient(mut self, recipient: impl Into<String>) -> Self {
        self.recipient = Some(recipient.into());
        self
    }

    pub fn location(mut self, location: impl Into<String>) -> Self {
        self.modifiers.push(Modifier::Location(location.into()));
        self
    }

    pub fn time(mut self, time: impl Into<String>) -> Self {
        self.modifiers.push(Modifier::Time(time.into()));
        self
    }

    pub fn manner(mut self, manner: impl Into<String>) -> Self {
        self.modifiers.push(Modifier::Manner(manner.into()));
        self
    }

    pub fn tense(mut self, tense: Tense) -> Self {
        self.tense = tense;
        self
    }

    pub fn aspect(mut self, aspect: Aspect) -> Self {
        self.aspect = aspect;
        self
    }

    pub fn negative(mut self) -> Self {
        self.negative = true;
        self
    }
}

#[derive(Clone, Debug)]
pub struct LangPack {
    pub noun_values: HashMap<String, String>,
    pub verb_values: HashMap<String, String>,
    pub parent_lang: Option<Box<LangPack>>,
}

impl LangPack {
    pub fn noun<'a>(&'a self, key: &'a str) -> &'a str {
        if let Some(noun) = self.noun_values.get(key) {
            return noun.as_str();
        }

        if let Some(parent) = &self.parent_lang {
            return parent.noun(key);
        }

        key
    }

    pub fn verb<'a>(&'a self, key: &'a str) -> &'a str {
        if let Some(verb) = self.verb_values.get(key) {
            return verb.as_str();
        }

        if let Some(parent) = &self.parent_lang {
            return parent.verb(key);
        }

        key
    }
}

pub fn load_noun_keys() -> Vec<NounKeyData> {
    serde_json::from_str(include_str!("res/noun_key.json")).unwrap()
}

pub fn load_verb_keys() -> Vec<VerbKeyData> {
    serde_json::from_str(include_str!("res/verb_key.json")).unwrap()
}

pub fn load_json_map(text: &str) -> HashMap<String, String> {
    serde_json::from_str(text).unwrap()
}