random_picker/lib.rs
1//! Generates random choices based on the weight table of probabilities.
2//! It can be used to calculate each item's probability of being picked up
3//! when picking a given amount of non-repetitive items, or to compare
4//! the speed of OS random source with that of the CSPRNG.
5
6// by wuwbobo2021 <https://github.com/wuwbobo2021>, <wuwbobo@outlook.com>
7
8mod calc;
9mod config;
10mod picker;
11
12pub use crate::{config::*, picker::*};
13
14/// Convenience wrapper for exactly one picking operation.
15///
16/// ```
17/// let picks: Vec<String> = random_picker::pick(2,
18/// "a=1;b=15;c=1.5".parse().unwrap()
19/// ).unwrap();
20/// // nonrepetitive by default
21/// assert!(picks.iter().any(|k| k == "a" || k == "c"));
22/// ```
23pub fn pick<T>(amount: usize, conf: Config<T>) -> Result<Vec<T>, Error>
24where
25 T: Clone + Eq + std::hash::Hash,
26{
27 Picker::build(conf)?.pick(amount)
28}
29
30/// Possible errors returned by functions in this crate.
31#[derive(Debug)]
32pub enum Error {
33 /// The table is invalid and cannot be used by the picker.
34 InvalidTable,
35 /// The given amount exceeds the amount of possible items in the table.
36 InvalidAmount,
37 /// Error from the random generator.
38 RandError(rand::Error),
39 /// Failure of the multi-thread probability calculator.
40 ThreadError,
41}
42
43impl std::fmt::Display for Error {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 use Error::*;
46 match self {
47 InvalidTable => write!(f, "Invalid probability table"),
48 InvalidAmount => write!(f, "Invalid amount of items to be picked up"),
49 RandError(e) => write!(f, "RNG Error: {:?}", e),
50 ThreadError => write!(f, "Thread error during calculation"),
51 }
52 }
53}
54
55impl std::error::Error for Error {}