Struct Config

Source
pub struct Config<T: Clone + Eq + Hash> {
    pub table: Table<T>,
    pub inversed: bool,
    pub repetitive: bool,
}
Expand description

Configuration required by Picker. All members are public and are supposed to be modified by the user.

Fields§

§table: Table<T>

Table of choices and weights which are proportional to the probabilities on repetitive mode or single-item mode.

§inversed: bool

Do multiplicative inversion for each value in the table.

§repetitive: bool

Allow the same item to be picked for multiple times in the result.

Implementations§

Source§

impl<T: Clone + Eq + Hash> Config<T>

Source

pub fn calc_probabilities(&self, pick_amount: usize) -> Result<Table<T>, Error>

Calculates probabilities of existences of table items in each picking result of length pick_amount. In non-repetitive mode, the multi-thread tree algorithm may be used.

Preorder traversal is performed in each thread. Something like depth-first or postorder algorithm may achieve higher precision (consider the error produced while adding a small floating-point number to a much larger number, which is the current way), but it will probably increase complexity and memory usage.

TODO: figure out why its single-thread performance is about 7% slower than the single-thread C++ version compiled with clang++ without -march=native, and unsafe operations can’t make this Rust program faster. It is faster than the C++ version compiled with GCC, though.

Source§

impl<T: Clone + Eq + Hash> Config<T>

Source

pub fn new() -> Self

Returns an invalid configuration with an empty table. Please add items into the table before using it to construct Picker.

let conf = random_picker::Config::<String>::new();
assert!(!conf.inversed && !conf.repetitive);
assert!(conf.check().is_err());
Source

pub fn check(&self) -> Result<(), Error>

Checks whether or not the table can be used by Picker.

let mut conf: random_picker::Config<String> = "
    a = -1; b = 0; c = 2
".parse().unwrap();
assert!(conf.check().is_err());
conf.table.insert("a".to_string(), 1.);
assert!(conf.check().is_ok());
conf.inversed = true;
assert!(conf.check().is_err());
conf.table.insert("b".to_string(), 0.1);
assert!(conf.check().is_ok());
Source

pub fn is_fair(&self) -> bool

Returns true if all items have equal (and valid) weight values.

let mut conf: random_picker::Config<String> = "
    a = -1; b = 1; c = 1.1
".parse().unwrap();
assert!(!conf.is_fair());
conf.table.insert("a".to_string(), 1.);
assert!(!conf.is_fair());
conf.table.insert("c".to_string(), 1.);
assert!(conf.is_fair());
Source§

impl Config<String>

Source

pub fn append_str(&mut self, str_items: &str)

Appends, modifies or deletes items in the table according to the configuration input string.

let mut conf: random_picker::Config<String> = "
# 'repetitive' and 'inversed' are special items
repetitive = true
inversed = false
# this line can be ignored
[items]
oxygen = 47
silicon = 28
aluminium=8; iron=5; magnesium=4;
calcium=2; potassium=2; sodium=2
others = 2; nonexistium = 31
   aluminium 7.9; delete nonexistium
".parse().unwrap();
assert_eq!(conf.table.len(), 9);
assert_eq!(conf.repetitive, true);
assert_eq!(conf.inversed, false);
assert_eq!(conf.table.get("aluminium"), Some(&7.9));

conf.append_str("\
# power_inversed/repetitive_picking without '=' are for the old format
power_inversed
# invalid: repetitive = 0 (0 is not bool)
repetitive = 0
silicon = 28.1
");
assert_eq!(conf.inversed, true);

conf.append_str("inversed = false");
assert_eq!(conf, random_picker::Config {
    table: [
        ("oxygen", 47.), ("silicon", 28.1), ("aluminium", 7.9),
        ("iron", 5.), ("magnesium", 4.), ("calcium", 2.),
        ("sodium", 2.), ("potassium", 2.), ("others", 2.),
    ].iter().map(|&(k, v)| (k.to_string(), v)).collect(),
    inversed: false,
    repetitive: true
});

Trait Implementations§

Source§

impl<T: Clone + Clone + Eq + Hash> Clone for Config<T>

Source§

fn clone(&self) -> Config<T>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + Clone + Eq + Hash> Debug for Config<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Clone + Eq + Hash> Default for Config<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Display for Config<String>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl FromStr for Config<String>

Source§

type Err = Error

The associated error which can be returned from parsing.
Source§

fn from_str(s: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
Source§

impl<T: PartialEq + Clone + Eq + Hash> PartialEq for Config<T>

Source§

fn eq(&self, other: &Config<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: Clone + Eq + Hash> StructuralPartialEq for Config<T>

Auto Trait Implementations§

§

impl<T> Freeze for Config<T>

§

impl<T> RefUnwindSafe for Config<T>
where T: RefUnwindSafe,

§

impl<T> Send for Config<T>
where T: Send,

§

impl<T> Sync for Config<T>
where T: Sync,

§

impl<T> Unpin for Config<T>
where T: Unpin,

§

impl<T> UnwindSafe for Config<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V