1use rand::SeedableRng;
4use rand::rngs::StdRng;
5use std::cell::RefCell;
6use std::rc::Rc;
7
8thread_local! {
9 static _FAKER_CONFIG: Rc<RefCell<FakerConfig>> = Rc::new(RefCell::new(FakerConfig::default()));
10}
11
12#[derive(Clone, Debug)]
14pub struct FakerConfig {
15 pub locale: String,
17 pub rng: Rc<RefCell<StdRng>>,
19}
20
21impl Default for FakerConfig {
22 fn default() -> Self {
23 Self {
24 locale: "en".to_string(),
25 rng: Rc::new(RefCell::new(StdRng::from_entropy())),
26 }
27 }
28}
29
30impl FakerConfig {
31 pub fn current() -> Self {
33 _FAKER_CONFIG.with(|config| config.borrow().clone())
34 }
35
36 pub fn set_locale(locale: &str) {
38 _FAKER_CONFIG.with(|config| {
39 config.borrow_mut().locale = locale.to_string();
40 });
41 }
42
43 pub fn locale() -> String {
45 _FAKER_CONFIG.with(|config| config.borrow().locale.clone())
46 }
47
48 pub fn set_seed(seed: u64) {
50 _FAKER_CONFIG.with(|config| {
51 config.borrow_mut().rng = Rc::new(RefCell::new(StdRng::seed_from_u64(seed)));
52 });
53 }
54
55 pub fn rand_u32(&self, max: u32) -> u32 {
57 use rand::Rng;
58 self.rng.borrow_mut().gen_range(0..max)
59 }
60
61 pub fn rand_usize(&self, max: usize) -> usize {
63 use rand::Rng;
64 self.rng.borrow_mut().gen_range(0..max)
65 }
66
67 pub fn rand_range(&self, min: u32, max: u32) -> u32 {
69 if max <= min {
70 return min;
71 }
72 let range = min..max;
74 use rand::Rng;
75 let mut rng = self.rng.borrow_mut();
76 rng.gen_range(range)
77 }
78
79 pub fn rand_range_i64(&self, min: i64, max: i64) -> i64 {
81 if max <= min {
82 return min;
83 }
84 let range = min..max;
85 use rand::Rng;
86 let mut rng = self.rng.borrow_mut();
87 rng.gen_range(range)
88 }
89
90 pub fn rand_f64(&self) -> f64 {
92 use rand::Rng;
93 let mut rng = self.rng.borrow_mut();
94 let a: u32 = rng.gen_range(0..1000000);
95 (a as f64) / 1000000.0
96 }
97
98 pub fn rand_bool(&self) -> bool {
100 use rand::Rng;
101 let mut rng = self.rng.borrow_mut();
102 rng.gen_range(0..2) == 1
103 }
104
105 pub fn rand_char(&self, chars: &[char]) -> char {
107 if chars.is_empty() {
108 return 'a'; }
110 let idx = self.rand_range(0, chars.len() as u32) as usize;
111 chars[idx]
112 }
113
114 pub fn sample<T: Clone>(&self, items: &[T]) -> T {
116 if items.is_empty() {
117 return items
118 .first()
119 .cloned()
120 .unwrap_or_else(|| panic!("Cannot sample from empty slice"));
121 }
122 let idx = self.rand_range(0, items.len() as u32) as usize;
123 items[idx].clone()
124 }
125
126 #[allow(clippy::ptr_arg)]
128 pub fn shuffle<T>(&self, vec: &mut Vec<T>) {
129 use rand::seq::SliceRandom;
130 vec.shuffle(&mut *self.rng.borrow_mut());
131 }
132}