112 lines
2.9 KiB
Rust
112 lines
2.9 KiB
Rust
//! Version 0 Prefstrings
|
|
|
|
use crate::{
|
|
InstanceSettings,
|
|
user_preferences::{Preference, ParseError},
|
|
WeightedTable,
|
|
};
|
|
|
|
/// A parsed version of the V0 prefstring
|
|
///
|
|
/// See the [prefstring specification][1] for more information about how this is interpretted.
|
|
///
|
|
/// [1]: https://fem.mint.lgbt/Emi/PronounsToday/raw/branch/main/doc/User-Preference-String-Spec.txt
|
|
pub struct UserPreferencesV0 {
|
|
pub default_weight: u8,
|
|
pub default_enabled: bool,
|
|
pub commands: Vec<Command>,
|
|
}
|
|
|
|
impl Preference for UserPreferencesV0 {
|
|
fn into_weighted_table<'a>(&self, settings: &'a InstanceSettings) -> WeightedTable<'a> {
|
|
todo!()
|
|
}
|
|
|
|
/// ```
|
|
/// # use pronouns_today::user_preferences::{Preference, v0::{Command, UserPreferencesV0}};
|
|
/// let pbytes = &[ 0x00, 0x81, 0x08, 0xcf, 0x80 ][..];
|
|
/// let prefs = UserPreferencesV0::from_prefstring_bytes(&pbytes).unwrap();
|
|
/// assert_eq!(prefs.default_weight, 1);
|
|
/// assert!(prefs.default_enabled);
|
|
/// assert_eq!(prefs.commands, vec![
|
|
/// Command::SetWeight(8),
|
|
/// Command::Move { toggle_enabled: true, distance: 15 },
|
|
/// Command::Move { toggle_enabled: false, distance: 0 },
|
|
/// ]);
|
|
/// ```
|
|
fn from_prefstring_bytes(pbytes: &[u8]) -> Result<Self, ParseError> {
|
|
|
|
// Some simple error checks
|
|
if pbytes.len() == 0 {
|
|
return Err(ParseError::ZeroLengthPrefstring);
|
|
} else if pbytes[0] != 00 {
|
|
return Err(ParseError::VersionMismatch {
|
|
expected_version: 0..1,
|
|
expected_variant: 0..1,
|
|
actual_version_byte: pbytes[0],
|
|
})
|
|
} else if pbytes.len() == 1 {
|
|
return Err(
|
|
ParseError::MalformedContent(
|
|
"Version 0 prefstrings must be at least two bytes long, but this one
|
|
was just one byte long".into()
|
|
)
|
|
)
|
|
}
|
|
|
|
// Extract the defaults from byte 1
|
|
Ok(UserPreferencesV0 {
|
|
default_enabled: pbytes[1] & 0b10000000 > 0,
|
|
default_weight: pbytes[1] & 0b01111111,
|
|
commands: pbytes[2..].iter().map(|b| Command::from(*b)).collect(),
|
|
})
|
|
}
|
|
|
|
fn into_prefstring_bytes(&self) -> Vec<u8> {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
|
pub enum Command {
|
|
SetWeight(u8),
|
|
Move {
|
|
toggle_enabled: bool,
|
|
distance: u8,
|
|
}
|
|
}
|
|
|
|
impl From<u8> for Command {
|
|
/// ```
|
|
/// use pronouns_today::user_preferences::v0::Command;
|
|
/// assert_eq!(
|
|
/// Command::from(0b01001000),
|
|
/// Command::SetWeight(0b01001000)
|
|
/// );
|
|
/// assert_eq!(
|
|
/// Command::from(0b11000000),
|
|
/// Command::Move {
|
|
/// toggle_enabled: true,
|
|
/// distance: 0b00000000
|
|
/// }
|
|
/// );
|
|
/// assert_eq!(
|
|
/// Command::from(0b10101000),
|
|
/// Command::Move {
|
|
/// toggle_enabled: false,
|
|
/// distance: 0b00101000
|
|
/// }
|
|
/// );
|
|
/// ```
|
|
fn from(b: u8) -> Self {
|
|
if b & 0b10000000 > 0 {
|
|
Command::Move {
|
|
toggle_enabled: b & 0b01000000 > 0,
|
|
distance: b & 0b00111111,
|
|
}
|
|
} else {
|
|
Command::SetWeight(b)
|
|
}
|
|
}
|
|
}
|