//! Pronoun selection & parsing for various version of user preferences //! //! There may be several possible representations of parsed prefstrings, each of which possibly //! with a different algorithm for selecting pronouns, and a different way of parsing itself. This //! module houses the implementations for each of these versions. pub mod v0; use crate::{InstanceSettings, WeightedTable}; use data_encoding::{BASE32_NOPAD, DecodeError}; /// A user's preferences for the probabilities of certain pronouns /// /// This is the parsed version of a prefstring. The actual implementation details may vary across /// versions, but universally they must be able to at least produce a weighted list of pronouns, /// representing the probabilities the user wants for each pronoun set. /// /// To this end, all versions of the user preferences implement [`Preference`]. For convenience, /// `UserPreferences` also implements [`Preference`]. /// /// Because parsing a prefstring must be done in relation to an [`InstanceSettings`], the /// `UserPreferences` struct shares a lifetime with the settings it was created with. #[non_exhaustive] pub enum UserPreferences<'a> { V0(v0::UserPreferencesV0<'a>) } /// Functionality provided by any version of user preferences /// /// See also: [`UserPreferences`] pub trait Preference<'a> { /// Produce a weighted list of pronouns based on these preferences /// /// This is a one-directional conversion to a [`WeightedTable`]. This method is a /// crucial step to randomly selecting a pronoun set based on a user's preferences, as /// any selection is done by using a [`WeightedTable`]. All preference versions must /// implement this method. fn into_weighted_table(&self) -> WeightedTable; /// Parse a given prefstring, after it's extraction from base64 /// /// This should attempt to parse the data contained in a prefstring into the appropriate /// format. Prefstrings will already have been parsed from base64 before being passed to the /// implementation. Users looking to turn a b64 prefstring into a `Preference` should use /// [`Preference::from_prefstring()`] fn from_prefstring_bytes(bytes: &[u8], settings: &'a InstanceSettings) -> Self where Self: Sized; /// Serialize these preferences into as few bytes as possible /// /// This should produce a series of bytes that, when passed to /// [`Preference::from_prefstring_bytes()`] should produce this `Preference` object again. /// This should be done in accordance with the [prefstring specification][1]. /// /// [1]: https://fem.mint.lgbt/Emi/PronounsToday/raw/branch/main/doc/User-Preference-String-Spec.txt fn into_prefstring_bytes(&self) -> Vec; /// Parse a base64 prefstring /// /// This is the primary method of creating a `Preference` object from a prefstring. The /// default implementation calls the underlying [`Preference::from_prefstring_bytes()`] method. fn from_prefstring(prefstring: &str, settings: &'a InstanceSettings) -> Result where Self: Sized { BASE32_NOPAD.decode(prefstring.as_ref()) .map(|ps| Self::from_prefstring_bytes(&ps, settings)) } /// Serialize into a base64 prefstring /// /// This is the primary method of creating a prefstring from a `Preference` object. The /// default implementation calls the underlying [`Preference::into_prefstring_bytes()`] method. fn into_prefstring(&self) -> String { BASE32_NOPAD.encode(&self.into_prefstring_bytes()) } } impl<'a> Preference<'a> for UserPreferences<'a> { fn into_weighted_table(&self) -> WeightedTable { match self { UserPreferences::V0(pref) => pref, }.into_weighted_table() } fn from_prefstring_bytes(bytes: &[u8], settings: &'a InstanceSettings) -> Self { todo!() } fn into_prefstring_bytes(&self) -> Vec { todo!() } }