2021-10-21 18:38:37 +00:00
|
|
|
//! The algorithms powering pronouns.today - Random pronouns generated daily
|
|
|
|
//!
|
|
|
|
//! This library contains all of the functionality for selecting a random pronoun based off of a
|
|
|
|
//! user's preferences, including parsing various preference string (prefstring) versions,
|
|
|
|
//! generating a weighted table based off of user preferences, and selecting a pronoun set based
|
|
|
|
//! off of that weighted table.
|
|
|
|
//!
|
|
|
|
//! ## Basic Usage
|
|
|
|
//!
|
|
|
|
//! ```
|
|
|
|
//! use pronouns_today::InstanceSettings;
|
|
|
|
//!
|
2021-10-21 22:33:38 +00:00
|
|
|
//! let instance_settings = InstanceSettings::default(); // Or load from a config file
|
2021-10-21 18:38:37 +00:00
|
|
|
//!
|
|
|
|
//! // When you receive a request
|
|
|
|
//! let user_name = Some("Emi");
|
|
|
|
//! let user_prefstr = Some("acaqqbykawbag");
|
|
|
|
//! let pronouns = instance_settings.select_pronouns(user_name, user_prefstr);
|
|
|
|
//!
|
|
|
|
//! println!("Your pronouns are: {}", pronouns);
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! ## Advanced Usage
|
|
|
|
//!
|
|
|
|
//! The `InstanceSettings::select_pronouns()` method is really just a shorthand for the
|
|
|
|
//! more complex process going on behind the scenes. In reality, there are several steps
|
|
|
|
//! used to select the pronouns. Each step can be modified or run individually for
|
|
|
|
//! greater control.
|
|
|
|
//!
|
|
|
|
//! 1. Configure the [`InstanceSettings`] from a config or default
|
|
|
|
//! 2. Parse the user's prefstring with [`UserPreferences::from_prefstring()`][up]
|
|
|
|
//! 3. Produce a weighted table from the preferences using
|
|
|
|
//! [`UserPreferences::into_weighted_table()`][up]
|
|
|
|
//! 4. Roll a pronoun set from the weighted table with one of the methods in the
|
|
|
|
//! [`WeightedTable`] struct.
|
|
|
|
//! 5. Render the [`Pronoun`]s with one of the provided methods, or use the forms
|
|
|
|
//! individually.
|
|
|
|
//!
|
|
|
|
//! [up]: UserPreferences
|
|
|
|
|
2021-10-21 04:18:41 +00:00
|
|
|
pub mod user_preferences;
|
2021-10-22 03:06:14 +00:00
|
|
|
pub mod util;
|
2021-10-21 18:37:37 +00:00
|
|
|
mod weighted_table;
|
|
|
|
|
|
|
|
use std::fmt;
|
2021-10-21 04:18:41 +00:00
|
|
|
|
|
|
|
use serde::{Serialize, Deserialize, self};
|
|
|
|
|
2021-10-21 18:37:37 +00:00
|
|
|
pub use weighted_table::WeightedTable;
|
|
|
|
pub use user_preferences::UserPreferences;
|
|
|
|
|
2021-10-21 04:18:41 +00:00
|
|
|
/// Runtime-constant setting that apply to an entire pronouns.today instance
|
|
|
|
///
|
|
|
|
/// These are values specified by the instance operator through the pronouns.today config file.
|
|
|
|
///
|
|
|
|
/// This is also the struct that is used to perform the majority of operations pertaining parsing
|
|
|
|
/// user preference strings (prefstrings). Utility methods are also provided for parsing a
|
|
|
|
/// prefstring and then selecting a pronoun with it all at once.
|
|
|
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
|
|
|
pub struct InstanceSettings {
|
|
|
|
|
|
|
|
/// A list of pronouns recognized by the instance
|
|
|
|
pub pronoun_list: Vec<Pronoun>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InstanceSettings {
|
|
|
|
|
|
|
|
/// Parse a prefstring and then immediately select pronouns from it.
|
|
|
|
///
|
|
|
|
/// This is shorthand for
|
|
|
|
///
|
|
|
|
/// ```
|
2021-10-21 22:33:38 +00:00
|
|
|
/// # use pronouns_today::InstanceSettings;
|
|
|
|
/// # let settings = InstanceSettings::default();
|
|
|
|
/// # let name = String::from("Sashanora");
|
|
|
|
/// # let prefstring = String::from("todo");
|
2021-10-21 04:18:41 +00:00
|
|
|
/// let pronouns = settings.parse_prefstring(Some(&prefstring)).select_pronouns(Some(&name));
|
|
|
|
/// # assert_eq!(pronouns, settings.select_pronouns(Some(&name), Some(&prefstring)));
|
|
|
|
/// ```
|
|
|
|
pub fn select_pronouns(&self, name: Option<impl AsRef<str>>, pref_string: Option<impl AsRef<str>>) -> &str {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
2021-10-21 18:38:20 +00:00
|
|
|
}
|
2021-10-21 04:18:41 +00:00
|
|
|
|
2021-10-21 18:38:20 +00:00
|
|
|
impl Default for InstanceSettings {
|
|
|
|
fn default() -> Self {
|
|
|
|
let pronouns: Vec<Pronoun> = vec![
|
|
|
|
["she", "her", "her", "hers", "herself" ].into(),
|
|
|
|
["he", "him", "his", "his", "himself" ].into(),
|
|
|
|
["they", "them", "their", "theirs", "themself" ].into(),
|
|
|
|
["it", "it", "its", "its", "itself" ].into(),
|
|
|
|
["xe", "xem", "xyr", "xyrs", "xemself" ].into(),
|
|
|
|
["ze", "zem", "zyr", "zyrs", "zemself" ].into(),
|
|
|
|
["fae", "faer", "faer", "faers", "faerself" ].into(),
|
|
|
|
["ne", "nem", "nir", "nirs", "nirself" ].into(),
|
|
|
|
["e", "em", "eir", "eirs", "eirself" ].into(),
|
|
|
|
["vey", "vem", "ver", "vers", "verself" ].into(),
|
|
|
|
];
|
|
|
|
InstanceSettings {
|
|
|
|
pronoun_list: pronouns
|
|
|
|
}
|
|
|
|
}
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A standard five-form pronoun set
|
|
|
|
///
|
|
|
|
/// All pronouns are configured as five-form pronoun set. This is necessary in order to display
|
|
|
|
/// example sentances to the user. However, typically only two or three forms of the pronoun are
|
|
|
|
/// used to display the pronoun. For example, she/her/her/hers/herself would typically be written
|
|
|
|
/// she/her or she/her/hers.
|
|
|
|
///
|
|
|
|
/// Methods are provided to quickly generate these shorter forms, as well as example sentences.
|
|
|
|
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)]
|
|
|
|
#[serde(from = "[String; 5]", into = "[String; 5]")]
|
|
|
|
pub struct Pronoun {
|
|
|
|
|
|
|
|
/// The pronoun's form when used as a subject
|
|
|
|
///
|
|
|
|
/// For "she", this is "she", as in
|
|
|
|
///
|
|
|
|
/// > *She* went to the park.
|
|
|
|
pub subject_pronoun: String,
|
|
|
|
|
|
|
|
/// The pronoun's form when used as an object
|
|
|
|
///
|
|
|
|
/// For "she", this is "her", as in
|
|
|
|
///
|
|
|
|
/// > I went with *her*
|
|
|
|
pub object_pronoun: String,
|
|
|
|
|
|
|
|
/// The pronoun's form when used as a possesive determiner
|
|
|
|
///
|
|
|
|
/// For "she", this is "her", as in
|
|
|
|
///
|
|
|
|
/// > I have *her* frisbee
|
|
|
|
pub possesive_determiner: String,
|
|
|
|
|
|
|
|
/// The pronoun's form when used as a possesive pronoun
|
|
|
|
///
|
|
|
|
/// For "she", this is "hers", as in
|
|
|
|
///
|
|
|
|
/// > At least I think it is *hers*.
|
|
|
|
pub possesive_pronoun: String,
|
|
|
|
|
|
|
|
/// The pronoun's form when used reflexively
|
|
|
|
///
|
|
|
|
/// For "she", this is "herself", as in
|
|
|
|
///
|
|
|
|
/// > She did it herself
|
|
|
|
pub reflexive_pronoun: String,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-10-21 18:38:20 +00:00
|
|
|
impl Pronoun {
|
|
|
|
pub fn render_threeform(&self) -> String {
|
|
|
|
format!("{}/{}/{}", self.subject_pronoun, self.object_pronoun, self.possesive_pronoun)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Pronoun {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.write_str(&self.render_threeform())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 04:18:41 +00:00
|
|
|
impl From<[String; 5]> for Pronoun {
|
|
|
|
fn from(five_form: [String; 5]) -> Self {
|
|
|
|
let mut five_form = IntoIterator::into_iter(five_form);
|
|
|
|
// If anyone knows a better way of deconstructing this, *please* let me know, or PR
|
|
|
|
Pronoun {
|
|
|
|
subject_pronoun: five_form.next().unwrap(),
|
|
|
|
object_pronoun: five_form.next().unwrap(),
|
|
|
|
possesive_determiner: five_form.next().unwrap(),
|
|
|
|
possesive_pronoun: five_form.next().unwrap(),
|
|
|
|
reflexive_pronoun: five_form.next().unwrap(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 18:38:20 +00:00
|
|
|
impl From<[&str; 5]> for Pronoun {
|
|
|
|
fn from(five_form: [&str; 5]) -> Self {
|
|
|
|
(&five_form).into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 04:18:41 +00:00
|
|
|
impl From<&[&str; 5]> for Pronoun {
|
|
|
|
fn from(five_form: &[&str; 5]) -> Self {
|
|
|
|
Pronoun {
|
2021-10-21 18:38:20 +00:00
|
|
|
subject_pronoun: five_form[0].to_string(),
|
|
|
|
object_pronoun: five_form[1].to_string(),
|
|
|
|
possesive_determiner: five_form[2].to_string(),
|
|
|
|
possesive_pronoun: five_form[3].to_string(),
|
|
|
|
reflexive_pronoun: five_form[4].to_string(),
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Pronoun> for [String; 5] {
|
|
|
|
fn from(pronoun: Pronoun) -> Self {
|
|
|
|
[
|
|
|
|
pronoun.subject_pronoun,
|
|
|
|
pronoun.object_pronoun,
|
|
|
|
pronoun.possesive_determiner,
|
|
|
|
pronoun.possesive_pronoun,
|
|
|
|
pronoun.reflexive_pronoun,
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|