choose_rand/lib.rs
1//! # choose-rand
2//! A small crate for choosing random items from a list of weighted items.
3//!
4//! ### Example
5//! ```rust
6//! use choose_rand::prelude::*;
7//!
8//! #[derive(Debug, Clone)]
9//! struct Foo {
10//! prob: f32,
11//! }
12//!
13//! impl Probable for Foo {
14//! fn probability(&self) -> f32 {
15//! self.prob
16//! }
17//! }
18//!
19//! fn main() -> Result<()> {
20//! let v: Vec<_> = choose_rand::helper::refcellify(
21//! vec![Foo { prob: 0.25 }, Foo { prob: 0.5 }, Foo { prob: 0.1 }, Foo { prob: 0.05 }]
22//! ).collect();
23//!
24//! let mut rng = rand::thread_rng();
25//! dbg!(v.choose_rand(&mut rng));
26//!
27//! Ok(())
28//! }
29//! ```
30
31#[warn(missing_docs)]
32
33/// Contains all of the important things from this crate.
34/// When using the crate, you want to do `use choose_rand::prelude::*;`
35pub mod prelude;
36
37/// Adds all the main parts of the crate, including the traits required for the crate to work
38pub mod rand;
39
40/// Contains the error enum for this crate.
41pub mod error;
42
43/// Contains some simple helper functions to make life easier when using this crate.
44pub mod helper;
45
46#[cfg(test)]
47mod tests {
48
49 use super::helper::*;
50 use super::prelude::*;
51
52 #[derive(Debug, Clone)]
53 struct Foo(f32, Option<String>);
54
55 impl Probable for Foo {
56 fn probability(&self) -> f32 {
57 self.0
58 }
59 }
60
61 #[test]
62 fn vec() -> Result<()> {
63 let v: Vec<_> = refcellify(vec![
64 Foo(0.1, None),
65 Foo(0.25, None),
66 Foo(0.5, None),
67 Foo(0.15, None),
68 ])
69 .collect();
70
71 let mut chosen = Vec::with_capacity(100);
72
73 let mut rng = rand::thread_rng();
74
75 for _ in 0..100 {
76 chosen.push(v.choose_rand(&mut rng)?);
77 }
78
79 dbg!(chosen);
80
81 Ok(())
82 }
83
84 #[test]
85 fn vec_mut() -> Result<()> {
86 let mut v: Vec<_> = refcellify(
87 vec![
88 Foo(0.1, Some("hi".into())),
89 Foo(0.25, Some("hello".into())),
90 Foo(0.5, Some("hola".into())),
91 Foo(0.15, Some("bonjour".into())),
92 ]
93 .into_iter(),
94 )
95 .collect();
96
97 let mut rng = rand::thread_rng();
98
99 let mut chosen = Vec::with_capacity(100);
100
101 for _ in 0..100 {
102 let mut c = v.choose_rand_mut(&mut rng)?;
103
104 if let Some(s) = &mut c.1 {
105 s.push('!');
106 }
107
108 chosen.push(c.clone()); // cloned so we can see each version of it. without clone, all copies of it should change in `chosen`
109 }
110
111 dbg!(chosen, v);
112
113 Ok(())
114 }
115}