wb_cache/test/simulation/scriptwriter/entity/
customer.rs1use fieldx::fxstruct;
2use rand_distr::Distribution;
3use rand_distr::Gamma;
4use rand_distr::Poisson;
5
6use crate::test::simulation::db::entity::Customer as DbCustomer;
7use crate::test::simulation::types::simerr;
8use crate::test::simulation::types::Result;
9
10#[derive(Clone, Debug)]
11#[fxstruct(no_new, builder(post_build), get)]
12pub struct Customer {
13 #[fieldx(copy)]
14 pub id: i32,
15 pub first_name: String,
16 pub last_name: String,
17 pub email: String,
18 #[fieldx(copy, set, default(-1))]
19 pub registered_on: i32,
20
21 #[fieldx(copy)]
22 erratic_quotient: f64,
23 #[fieldx(copy)]
24 orders_per_day: f64,
25
26 #[fieldx(optional, builder(off), set(private), get("_nb_gamma", as_ref))]
29 nb_gamma: Gamma<f64>,
30}
31
32impl Customer {
33 fn post_build(mut self) -> Self {
34 let eq = self.erratic_quotient();
35 let shape = self.orders_per_day() / eq;
36 self.set_nb_gamma(Gamma::new(shape, eq).unwrap());
37
38 self
39 }
40
41 #[inline(always)]
42 pub fn nb_gamma(&self) -> &Gamma<f64> {
43 self._nb_gamma().unwrap()
44 }
45
46 pub fn daily_purchases(&self) -> Result<f64> {
47 let mut rng = &mut rand::rng();
48 let lambda = self.nb_gamma().sample(&mut rng);
49 if lambda == 0. {
50 return Ok(0.0);
51 }
52 Ok(Poisson::new(lambda)
53 .map_err(|err| {
54 let err = simerr!("Poisson(lambda={lambda}): {}", err);
55 err.context(format!(
56 "Customer EQ: {}; orders per day: {}",
57 self.erratic_quotient(),
58 self.orders_per_day()
59 ));
60 err
61 })?
62 .sample(&mut rng) as f64)
63 }
64}
65
66impl From<Customer> for DbCustomer {
67 fn from(customer: Customer) -> Self {
68 DbCustomer {
69 id: customer.id,
70 first_name: customer.first_name,
71 last_name: customer.last_name,
72 email: customer.email,
73 registered_on: customer.registered_on,
74 }
75 }
76}