2021-10-21 04:18:41 +00:00
|
|
|
//! Version 0 Prefstrings
|
|
|
|
|
2021-10-21 18:37:37 +00:00
|
|
|
use crate::{
|
|
|
|
InstanceSettings,
|
2021-10-22 03:06:14 +00:00
|
|
|
Pronoun,
|
2021-10-21 22:33:38 +00:00
|
|
|
user_preferences::{Preference, ParseError},
|
2021-10-21 18:37:37 +00:00
|
|
|
WeightedTable,
|
|
|
|
};
|
2021-10-21 04:18:41 +00:00
|
|
|
|
2021-10-22 01:48:13 +00:00
|
|
|
use std::{
|
|
|
|
collections::HashMap,
|
|
|
|
iter::{Extend, self},
|
|
|
|
};
|
|
|
|
|
2021-10-21 04:18:41 +00:00
|
|
|
/// 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
|
2021-10-24 04:01:48 +00:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
2021-10-21 19:05:52 +00:00
|
|
|
pub struct UserPreferencesV0 {
|
2021-10-21 22:33:38 +00:00
|
|
|
pub default_weight: u8,
|
|
|
|
pub default_enabled: bool,
|
|
|
|
pub commands: Vec<Command>,
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 19:05:52 +00:00
|
|
|
impl Preference for UserPreferencesV0 {
|
2021-10-24 00:46:56 +00:00
|
|
|
fn create_weighted_table<'a>(&self, settings: &'a InstanceSettings) -> Result<WeightedTable<&'a Pronoun>, ParseError> {
|
2021-10-22 01:48:13 +00:00
|
|
|
let mut remaining_pronouns = settings.pronoun_list.iter();
|
|
|
|
let mut weighted_pronouns = HashMap::with_capacity(settings.pronoun_list.len());
|
|
|
|
|
|
|
|
for command in &self.commands {
|
|
|
|
match command {
|
|
|
|
|
|
|
|
Command::SetWeight(weight) => {
|
|
|
|
if *weight > 0 {
|
|
|
|
weighted_pronouns.insert(
|
|
|
|
remaining_pronouns.next()
|
|
|
|
.ok_or(ParseError::PrefstringExceedsPronounCount)?,
|
|
|
|
*weight
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
Command::Move { toggle_enabled, distance } => {
|
|
|
|
|
|
|
|
let skipped_pronouns = iter::repeat_with(|| remaining_pronouns.next())
|
|
|
|
.take(*distance as usize)
|
|
|
|
.collect::<Option<Vec<_>>>()
|
|
|
|
.ok_or(ParseError::PrefstringExceedsPronounCount)?;
|
|
|
|
|
|
|
|
if self.default_enabled {
|
|
|
|
weighted_pronouns.extend(
|
|
|
|
skipped_pronouns
|
|
|
|
.into_iter()
|
|
|
|
.map(|pronoun| (pronoun, self.default_weight))
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
let last_enabled = *toggle_enabled != self.default_enabled;
|
|
|
|
let last_pronoun = remaining_pronouns.next()
|
|
|
|
.ok_or(ParseError::PrefstringExceedsPronounCount)?;
|
|
|
|
if last_enabled {
|
|
|
|
weighted_pronouns.insert(last_pronoun, self.default_weight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.default_enabled {
|
|
|
|
weighted_pronouns.extend(
|
|
|
|
remaining_pronouns
|
|
|
|
.into_iter()
|
|
|
|
.map(|pronoun| (pronoun, self.default_weight))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-10-22 03:06:14 +00:00
|
|
|
WeightedTable::new(weighted_pronouns)
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 22:33:38 +00:00
|
|
|
/// ```
|
|
|
|
/// # 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(),
|
|
|
|
})
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
|
2021-10-24 00:46:56 +00:00
|
|
|
fn as_prefstring_bytes(&self) -> Vec<u8> {
|
2021-10-24 00:30:48 +00:00
|
|
|
let mut defaults_byte = 0u8;
|
|
|
|
if self.default_enabled {
|
|
|
|
defaults_byte |= 0b10000000;
|
|
|
|
}
|
|
|
|
defaults_byte |= self.default_weight & 0b01111111;
|
2021-10-24 05:21:14 +00:00
|
|
|
vec![0, defaults_byte]
|
2021-10-24 00:30:48 +00:00
|
|
|
.into_iter()
|
|
|
|
.chain(self.commands.iter().map(|cmd| cmd.into()))
|
|
|
|
.collect()
|
|
|
|
}
|
2021-10-24 04:01:48 +00:00
|
|
|
|
|
|
|
fn from_preferences(prefs: &[u8]) -> Self where Self: Sized {
|
|
|
|
if prefs.is_empty() {
|
|
|
|
return Self::default();
|
|
|
|
}
|
|
|
|
let mut weight_counts = vec![0u8; *prefs.iter().max().unwrap() as usize + 1];
|
|
|
|
let mut num_zeros = 0;
|
|
|
|
for w in prefs {
|
|
|
|
if *w == 0 {
|
|
|
|
num_zeros += 1;
|
|
|
|
} else {
|
|
|
|
weight_counts[*w as usize] += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let default_weight = weight_counts
|
|
|
|
.iter()
|
|
|
|
.enumerate()
|
|
|
|
.max_by(|(_, v1), (_, v2)| v1.cmp(v2))
|
|
|
|
.map(|(w, _)| w as u8)
|
|
|
|
.unwrap();
|
|
|
|
let default_enabled = num_zeros < prefs.len() / 2;
|
|
|
|
let mut commands = Vec::new();
|
|
|
|
if default_enabled {
|
|
|
|
let mut last_default = -1;
|
|
|
|
for (i, w) in prefs.iter().enumerate() {
|
|
|
|
let i = i as isize;
|
|
|
|
if *w == default_weight {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
if i - last_default > 1 {
|
|
|
|
let toggle_enabled = *w == 0;
|
|
|
|
let distance = if toggle_enabled {
|
|
|
|
(i - last_default) as u8 - 1
|
|
|
|
} else {
|
|
|
|
(i - last_default) as u8 - 2
|
|
|
|
};
|
|
|
|
commands.push(Command::Move {
|
|
|
|
toggle_enabled,
|
|
|
|
distance
|
|
|
|
});
|
|
|
|
if !toggle_enabled {
|
|
|
|
commands.push(Command::SetWeight(*w));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
commands.push(Command::SetWeight(*w));
|
|
|
|
}
|
|
|
|
last_default = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let mut last_enabled = -1;
|
|
|
|
for (i, w) in prefs.iter().enumerate() {
|
|
|
|
let i = i as isize;
|
|
|
|
if *w == 0 {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
if i - last_enabled > 1 {
|
|
|
|
let toggle_enabled = *w == default_weight;
|
|
|
|
let distance = if toggle_enabled {
|
|
|
|
(i - last_enabled) as u8 - 1
|
|
|
|
} else {
|
|
|
|
(i - last_enabled) as u8 - 2
|
|
|
|
};
|
|
|
|
commands.push(Command::Move {
|
|
|
|
toggle_enabled,
|
|
|
|
distance
|
|
|
|
});
|
|
|
|
if !toggle_enabled {
|
|
|
|
commands.push(Command::SetWeight(*w));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
commands.push(Command::SetWeight(*w));
|
|
|
|
}
|
|
|
|
last_enabled = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Self {
|
|
|
|
default_weight,
|
|
|
|
default_enabled,
|
|
|
|
commands,
|
|
|
|
}
|
|
|
|
}
|
2021-10-24 00:30:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Default to all pronouns on with equal weight
|
|
|
|
/// TODO make this configurable
|
|
|
|
impl Default for UserPreferencesV0 {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
default_enabled: true,
|
|
|
|
default_weight: 1,
|
|
|
|
commands: vec![],
|
|
|
|
}
|
2021-10-21 04:18:41 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-21 22:33:38 +00:00
|
|
|
|
|
|
|
#[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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-10-22 01:48:13 +00:00
|
|
|
|
2021-10-24 00:30:48 +00:00
|
|
|
impl From<&Command> for u8 {
|
|
|
|
fn from(command: &Command) -> Self {
|
|
|
|
match command {
|
|
|
|
// Some these ands shouldn't be needed if the command is valid
|
|
|
|
Command::SetWeight(weight) => weight & 0b01111111,
|
|
|
|
Command::Move { toggle_enabled, distance } => {
|
|
|
|
0b10000000 | ((*toggle_enabled as u8) << 6) | (distance & 0b00111111)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-22 01:48:13 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2021-10-22 03:06:14 +00:00
|
|
|
use crate::{InstanceSettings, Pronoun, WeightedTable};
|
2021-10-22 01:48:13 +00:00
|
|
|
use crate::user_preferences::{Preference, ParseError};
|
|
|
|
use crate::user_preferences::v0::{UserPreferencesV0, Command};
|
|
|
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
fn testing_instance_settings() -> InstanceSettings {
|
|
|
|
InstanceSettings {
|
|
|
|
pronoun_list: 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(),
|
|
|
|
],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-22 03:06:14 +00:00
|
|
|
fn check_table(actual: WeightedTable<&Pronoun>, expected: Vec<(&str, u8)>) {
|
|
|
|
let actual_simplified = actual.weights()
|
|
|
|
.into_iter()
|
|
|
|
.filter(|(pronoun, weight)| **weight > 0)
|
|
|
|
.map(|(pronoun, weight)| (pronoun.subject_pronoun.as_str(), *weight))
|
2021-10-22 01:48:13 +00:00
|
|
|
.collect::<HashMap<&str, u8>>();
|
|
|
|
let expected_owned = expected.into_iter()
|
|
|
|
.map(|(pronoun, weight)| (pronoun, weight))
|
|
|
|
.collect::<HashMap<&str, u8>>();
|
|
|
|
|
|
|
|
assert_eq!(actual_simplified, expected_owned);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into_weighted_table_no_commands() {
|
|
|
|
let s = testing_instance_settings();
|
|
|
|
let p = UserPreferencesV0 {
|
|
|
|
default_enabled: true,
|
|
|
|
default_weight: 2,
|
|
|
|
commands: Vec::new(),
|
|
|
|
};
|
|
|
|
|
2021-10-24 00:46:56 +00:00
|
|
|
let table = p.create_weighted_table(&s).unwrap();
|
2021-10-22 01:48:13 +00:00
|
|
|
let expected_table = vec![
|
|
|
|
("she", 2),
|
|
|
|
("he", 2),
|
|
|
|
("they", 2),
|
|
|
|
("it", 2),
|
|
|
|
("xe", 2),
|
|
|
|
];
|
|
|
|
|
|
|
|
check_table(table, expected_table);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into_weighted_table_move_commands_select_deactivation() {
|
|
|
|
let s = testing_instance_settings();
|
|
|
|
let p = UserPreferencesV0 {
|
|
|
|
default_enabled: true,
|
|
|
|
default_weight: 3,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: false,
|
|
|
|
distance: 1
|
|
|
|
},
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 2
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-10-24 00:46:56 +00:00
|
|
|
let table = p.create_weighted_table(&s).unwrap();
|
2021-10-22 01:48:13 +00:00
|
|
|
let expected_table = vec![
|
|
|
|
("she", 3),
|
|
|
|
("he", 3),
|
|
|
|
("they", 3),
|
|
|
|
("it", 3),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into_weighted_table_weight_commands() {
|
|
|
|
let s = testing_instance_settings();
|
|
|
|
let p = UserPreferencesV0 {
|
|
|
|
default_enabled: false,
|
|
|
|
default_weight: 1,
|
|
|
|
commands: vec![
|
|
|
|
Command::SetWeight(5),
|
|
|
|
Command::SetWeight(4),
|
|
|
|
Command::SetWeight(3),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-10-24 00:46:56 +00:00
|
|
|
let table = p.create_weighted_table(&s).unwrap();
|
2021-10-22 01:48:13 +00:00
|
|
|
let expected_table = vec![
|
|
|
|
("she", 5),
|
|
|
|
("he", 4),
|
|
|
|
("they", 3),
|
|
|
|
];
|
|
|
|
|
|
|
|
check_table(table, expected_table);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into_weighted_table_combined_commands() {
|
|
|
|
let s = testing_instance_settings();
|
|
|
|
let p = UserPreferencesV0 {
|
|
|
|
default_enabled: false,
|
|
|
|
default_weight: 9,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 1
|
|
|
|
},
|
|
|
|
Command::SetWeight(5),
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: false,
|
|
|
|
distance: 0
|
|
|
|
},
|
|
|
|
Command::SetWeight(4),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-10-24 00:46:56 +00:00
|
|
|
let table = p.create_weighted_table(&s).unwrap();
|
2021-10-22 01:48:13 +00:00
|
|
|
let expected_table = vec![
|
|
|
|
("he", 9),
|
|
|
|
("they", 5),
|
|
|
|
("xe", 4),
|
|
|
|
];
|
|
|
|
|
|
|
|
check_table(table, expected_table);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into_weighted_table_move_past_boundry() {
|
|
|
|
let s = testing_instance_settings();
|
|
|
|
let p = UserPreferencesV0 {
|
|
|
|
default_enabled: false,
|
|
|
|
default_weight: 1,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 5
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-10-24 00:46:56 +00:00
|
|
|
let err = p.create_weighted_table(&s).unwrap_err();
|
2021-10-22 01:48:13 +00:00
|
|
|
assert_eq!(err, ParseError::PrefstringExceedsPronounCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into_weighted_table_set_weight_past_boundry() {
|
|
|
|
let s = testing_instance_settings();
|
|
|
|
let p = UserPreferencesV0 {
|
|
|
|
default_enabled: false,
|
|
|
|
default_weight: 1,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 4
|
|
|
|
},
|
|
|
|
Command::SetWeight(9),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-10-24 00:46:56 +00:00
|
|
|
let err = p.create_weighted_table(&s).unwrap_err();
|
2021-10-22 01:48:13 +00:00
|
|
|
assert_eq!(err, ParseError::PrefstringExceedsPronounCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into_weighted_table_zero_default_weight() {
|
|
|
|
let s = testing_instance_settings();
|
|
|
|
let p = UserPreferencesV0 {
|
|
|
|
default_enabled: true,
|
|
|
|
default_weight: 0,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 2
|
|
|
|
},
|
|
|
|
Command::SetWeight(3),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-10-24 00:46:56 +00:00
|
|
|
let table = p.create_weighted_table(&s).unwrap();
|
2021-10-22 01:48:13 +00:00
|
|
|
let expected_table = vec![
|
|
|
|
("it", 3),
|
|
|
|
];
|
|
|
|
|
|
|
|
check_table(table, expected_table);
|
|
|
|
}
|
2021-10-24 04:01:48 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_prefs_most_disabled1() {
|
|
|
|
let pref_vals = vec![0,1,2,0,0];
|
|
|
|
let expected_prefs = UserPreferencesV0 {
|
|
|
|
default_enabled: false,
|
|
|
|
default_weight: 2,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: false,
|
|
|
|
distance: 0,
|
|
|
|
},
|
|
|
|
Command::SetWeight(1),
|
|
|
|
Command::SetWeight(2),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
let prefs = UserPreferencesV0::from_preferences(&pref_vals);
|
|
|
|
assert_eq!(prefs, expected_prefs);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_prefs_most_disabled2() {
|
|
|
|
let pref_vals = vec![0,1,1,0,0,0,2];
|
|
|
|
let expected_prefs = UserPreferencesV0 {
|
|
|
|
default_enabled: false,
|
|
|
|
default_weight: 1,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 1,
|
|
|
|
},
|
|
|
|
Command::SetWeight(1),
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: false,
|
|
|
|
distance: 2,
|
|
|
|
},
|
|
|
|
Command::SetWeight(2),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
let prefs = UserPreferencesV0::from_preferences(&pref_vals);
|
|
|
|
assert_eq!(prefs, expected_prefs);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_prefs_most_disabled3() {
|
|
|
|
let pref_vals = vec![0,0,0,0,1,0,0,0,2];
|
|
|
|
let expected_prefs = UserPreferencesV0 {
|
|
|
|
default_enabled: false,
|
|
|
|
default_weight: 2,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: false,
|
|
|
|
distance: 3,
|
|
|
|
},
|
|
|
|
Command::SetWeight(1),
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 3,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
let prefs = UserPreferencesV0::from_preferences(&pref_vals);
|
|
|
|
assert_eq!(prefs, expected_prefs);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_prefs_most_enabled1() {
|
|
|
|
let pref_vals = vec![0,1,2,1,1];
|
|
|
|
let expected_prefs = UserPreferencesV0 {
|
|
|
|
default_enabled: true,
|
|
|
|
default_weight: 1,
|
|
|
|
commands: vec![
|
|
|
|
Command::SetWeight(0),
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: false,
|
|
|
|
distance: 0,
|
|
|
|
},
|
|
|
|
Command::SetWeight(2),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
let prefs = UserPreferencesV0::from_preferences(&pref_vals);
|
|
|
|
assert_eq!(prefs, expected_prefs);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_prefs_most_enabled2() {
|
|
|
|
let pref_vals = vec![1,0,0,1,1,1,2];
|
|
|
|
let expected_prefs = UserPreferencesV0 {
|
|
|
|
default_enabled: true,
|
|
|
|
default_weight: 1,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 1,
|
|
|
|
},
|
|
|
|
Command::SetWeight(0),
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: false,
|
|
|
|
distance: 2,
|
|
|
|
},
|
|
|
|
Command::SetWeight(2),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
let prefs = UserPreferencesV0::from_preferences(&pref_vals);
|
|
|
|
assert_eq!(prefs, expected_prefs);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_prefs_most_enabled3() {
|
|
|
|
let pref_vals = vec![1,1,1,1,0,1,1,1,2];
|
|
|
|
let expected_prefs = UserPreferencesV0 {
|
|
|
|
default_enabled: true,
|
|
|
|
default_weight: 1,
|
|
|
|
commands: vec![
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: true,
|
|
|
|
distance: 4,
|
|
|
|
},
|
|
|
|
Command::Move {
|
|
|
|
toggle_enabled: false,
|
|
|
|
distance: 2,
|
|
|
|
},
|
|
|
|
Command::SetWeight(2),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
let prefs = UserPreferencesV0::from_preferences(&pref_vals);
|
|
|
|
assert_eq!(prefs, expected_prefs);
|
|
|
|
}
|
2021-10-24 05:21:14 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_as_prefstring_bytes() {
|
|
|
|
let prefs = UserPreferencesV0::default();
|
|
|
|
let expected_bytes = vec![0 , 0b10000001];
|
|
|
|
assert_eq!(expected_bytes, prefs.as_prefstring_bytes());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_prefstring_bytes() {
|
|
|
|
let bytes = vec![0 , 0b10000001];
|
|
|
|
let prefs = UserPreferencesV0::from_prefstring_bytes(&bytes).unwrap();
|
|
|
|
let expected_prefs = UserPreferencesV0::default();
|
|
|
|
assert_eq!(expected_prefs, prefs);
|
|
|
|
}
|
2021-10-22 01:48:13 +00:00
|
|
|
}
|