2021-10-21 04:18:41 +00:00
|
|
|
//! 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;
|
2021-10-21 22:33:38 +00:00
|
|
|
mod error;
|
|
|
|
pub use error::ParseError;
|
2021-10-21 04:18:41 +00:00
|
|
|
|
2021-10-21 18:37:37 +00:00
|
|
|
use crate::{InstanceSettings, WeightedTable};
|
2021-10-21 04:18:41 +00:00
|
|
|
|
2021-10-21 22:33:38 +00:00
|
|
|
use data_encoding::BASE32_NOPAD;
|
2021-10-21 04:18:41 +00:00
|
|
|
|
|
|
|
/// 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
|
2021-10-21 18:37:37 +00:00
|
|
|
/// 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.
|
2021-10-21 04:18:41 +00:00
|
|
|
///
|
|
|
|
/// 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]
|
2021-10-21 19:05:52 +00:00
|
|
|
pub enum UserPreferences {
|
|
|
|
V0(v0::UserPreferencesV0)
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Functionality provided by any version of user preferences
|
|
|
|
///
|
|
|
|
/// See also: [`UserPreferences`]
|
2021-10-21 19:05:52 +00:00
|
|
|
pub trait Preference {
|
2021-10-21 04:18:41 +00:00
|
|
|
|
2021-10-21 18:37:37 +00:00
|
|
|
/// Produce a weighted list of pronouns based on these preferences
|
2021-10-21 04:18:41 +00:00
|
|
|
///
|
2021-10-21 18:38:37 +00:00
|
|
|
/// 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.
|
2021-10-21 19:05:52 +00:00
|
|
|
fn into_weighted_table<'a>(&self, settings: &'a InstanceSettings) -> WeightedTable<'a>;
|
2021-10-21 04:18:41 +00:00
|
|
|
|
|
|
|
/// 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()`]
|
2021-10-21 22:33:38 +00:00
|
|
|
fn from_prefstring_bytes(bytes: &[u8]) -> Result<Self, ParseError> where Self: Sized;
|
2021-10-21 04:18:41 +00:00
|
|
|
|
|
|
|
/// 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<u8>;
|
|
|
|
|
|
|
|
/// 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.
|
2021-10-21 22:33:38 +00:00
|
|
|
fn from_prefstring(prefstring: &str) -> Result<Self, ParseError> where Self: Sized {
|
2021-10-21 18:37:37 +00:00
|
|
|
BASE32_NOPAD.decode(prefstring.as_ref())
|
2021-10-21 22:33:38 +00:00
|
|
|
.map_err(ParseError::Base32Error)
|
|
|
|
.and_then(|ps| Self::from_prefstring_bytes(&ps))
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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 {
|
2021-10-21 18:37:37 +00:00
|
|
|
BASE32_NOPAD.encode(&self.into_prefstring_bytes())
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 19:05:52 +00:00
|
|
|
impl Preference for UserPreferences {
|
|
|
|
fn into_weighted_table<'a>(&self, settings: &'a InstanceSettings) -> WeightedTable<'a> {
|
2021-10-21 04:18:41 +00:00
|
|
|
match self {
|
|
|
|
UserPreferences::V0(pref) => pref,
|
2021-10-21 19:05:52 +00:00
|
|
|
}.into_weighted_table(settings)
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 22:33:38 +00:00
|
|
|
fn from_prefstring_bytes(bytes: &[u8]) -> Result<Self, ParseError> where Self: Sized {
|
2021-10-21 04:18:41 +00:00
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn into_prefstring_bytes(&self) -> Vec<u8> {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|