1
use std::collections::{BTreeMap, HashSet};
2
use std::ops::RangeInclusive;
3

            
4
use fake::faker::address::raw::{
5
    BuildingNumber, CityName, CountryCode, PostCode, StateName, StreetName, StreetSuffix,
6
};
7
use fake::faker::company::raw::{Bs, BsAdj};
8
use fake::faker::internet::raw::SafeEmail;
9
use fake::faker::lorem::raw::Paragraphs;
10
use fake::faker::name::raw::Name;
11
use fake::faker::phone_number::raw::PhoneNumber;
12
use fake::locales::EN;
13
use fake::{Dummy, Fake};
14
use rand::seq::SliceRandom;
15
use rand::Rng;
16
use serde::{Deserialize, Serialize};
17

            
18
use crate::utils::gen_range;
19

            
20
4
#[derive(Default, Clone, Debug)]
21
pub struct InitialDataSet {
22
    pub customers: BTreeMap<u32, Customer>,
23
    pub products: BTreeMap<u32, Product>,
24
    pub categories: BTreeMap<u32, Category>,
25
    pub orders: BTreeMap<u32, Order>,
26
    pub reviews: Vec<ProductReview>,
27
}
28

            
29
#[derive(Debug)]
30
pub struct InitialDataSetConfig {
31
    pub number_of_customers: RangeInclusive<u32>,
32
    pub number_of_products: RangeInclusive<u32>,
33
    pub number_of_categories: RangeInclusive<u32>,
34
    pub number_of_orders: RangeInclusive<u32>,
35
    pub number_of_reviews: RangeInclusive<u32>,
36
}
37

            
38
impl InitialDataSetConfig {
39
4
    pub fn fake<R: Rng>(&self, rng: &mut R) -> InitialDataSet {
40
4
        let mut data = InitialDataSet::default();
41
4
        let mut customer_names = HashSet::new();
42
427
        for customer_id in 0..gen_range(rng, self.number_of_customers.clone()) {
43
427
            let customer = Customer::fake(rng, &customer_names);
44
427
            customer_names.insert(customer.name.clone());
45
427
            data.customers.insert(customer_id, customer);
46
427
        }
47
59
        for category_id in 0..gen_range(rng, self.number_of_categories.clone()) {
48
59
            data.categories.insert(category_id, Category::fake(rng));
49
59
        }
50
4
        let mut product_names = HashSet::new();
51
437
        for product_id in 0..gen_range(rng, self.number_of_products.clone()) {
52
437
            let product = Product::fake(rng, &data.categories, &product_names);
53
437
            product_names.insert(product.name.clone());
54
437
            data.products.insert(product_id, product);
55
437
        }
56
4
        let customer_ids = data.customers.keys().copied().collect::<Vec<_>>();
57
4
        let product_ids = data.products.keys().copied().collect::<Vec<_>>();
58
1008
        for order_id in 0..gen_range(rng, self.number_of_orders.clone()) {
59
1008
            data.orders
60
1008
                .insert(order_id, Order::fake(rng, &customer_ids, &product_ids));
61
1008
        }
62
4
        let products_available_to_rate = data
63
4
            .orders
64
4
            .values()
65
1008
            .flat_map(|order| {
66
1008
                order
67
1008
                    .product_ids
68
1008
                    .iter()
69
9112
                    .map(|&product_id| (order.customer_id, product_id))
70
1008
            })
71
4
            .collect::<HashSet<_>>();
72
4
        let mut rated_products = HashSet::new();
73
4
        if !products_available_to_rate.is_empty() {
74
4
            for _ in 0..gen_range(rng, self.number_of_reviews.clone()) {
75
487
                if let Some(review) =
76
487
                    ProductReview::fake(rng, &products_available_to_rate, &mut rated_products)
77
487
                {
78
487
                    data.reviews.push(review);
79
487
                }
80
            }
81
        }
82

            
83
4
        data
84
4
    }
85
}
86

            
87
#[derive(Serialize, Deserialize, Debug)]
88
struct BenchmarkReport {}
89

            
90
1708
#[derive(Clone, Debug, Serialize, Deserialize)]
91
pub struct Customer {
92
    pub name: String,
93
    pub email: String,
94
    pub address: String,
95
    pub city: String,
96
    pub region: String,
97
    pub country: String,
98
    pub postal_code: String,
99
    pub phone: String,
100
}
101

            
102
impl Customer {
103
427
    pub fn fake<R: Rng>(rng: &mut R, taken_names: &HashSet<String>) -> Self {
104
427
        let name = loop {
105
427
            let name = format!(
106
427
                "{} {}",
107
427
                Name(EN).fake_with_rng::<String, _>(rng),
108
427
                rng.gen::<u8>()
109
427
            );
110
427
            if !taken_names.contains(&name) {
111
427
                break name;
112
            }
113
        };
114
427
        Self {
115
427
            name,
116
427
            email: SafeEmail(EN).fake_with_rng(rng),
117
427
            address: format!(
118
427
                "{} {} {}",
119
427
                BuildingNumber(EN).fake_with_rng::<String, _>(rng),
120
427
                StreetName(EN).fake_with_rng::<String, _>(rng),
121
427
                StreetSuffix(EN).fake_with_rng::<String, _>(rng)
122
427
            ),
123
427
            city: CityName(EN).fake_with_rng(rng),
124
427
            region: StateName(EN).fake_with_rng(rng),
125
427
            country: CountryCode(EN).fake_with_rng(rng),
126
427
            postal_code: PostCode(EN).fake_with_rng(rng),
127
427
            phone: PhoneNumber(EN).fake_with_rng(rng),
128
427
        }
129
427
    }
130
}
131

            
132
98780
#[derive(Clone, Debug, Serialize, Deserialize)]
133
pub struct Product {
134
    pub name: String,
135
    pub category_ids: Vec<u32>,
136
}
137

            
138
impl Product {
139
437
    pub fn fake<R: Rng>(
140
437
        rng: &mut R,
141
437
        available_categories: &BTreeMap<u32, Category>,
142
437
        taken_names: &HashSet<String>,
143
437
    ) -> Self {
144
437
        let mut available_category_ids = available_categories.keys().copied().collect::<Vec<_>>();
145
437
        let number_of_categories = if available_category_ids.is_empty() {
146
            0
147
        } else {
148
437
            rng.gen_range(0..(available_category_ids.len() + 1) / 2)
149
        };
150
437
        let mut category_ids = Vec::with_capacity(number_of_categories);
151
1545
        for _ in 0..number_of_categories {
152
1545
            let category_index = rng.gen_range(0..available_category_ids.len());
153
1545
            category_ids.push(available_category_ids.remove(category_index));
154
1545
        }
155

            
156
437
        let name = loop {
157
437
            let name = format!(
158
437
                "{} {}",
159
437
                Bs(EN).fake_with_rng::<String, _>(rng),
160
437
                rng.gen::<u8>()
161
437
            );
162
437
            if !taken_names.contains(&name) {
163
437
                break name;
164
            }
165
        };
166

            
167
437
        Self { name, category_ids }
168
437
    }
169
}
170

            
171
236
#[derive(Clone, Debug, Serialize, Deserialize)]
172
pub struct Category {
173
    pub name: String,
174
}
175

            
176
impl Category {
177
59
    pub fn fake<R: Rng>(rng: &mut R) -> Self {
178
59
        Self {
179
59
            name: BsAdj(EN).fake_with_rng(rng),
180
59
        }
181
59
    }
182
}
183

            
184
4548
#[derive(Clone, Debug, Serialize, Deserialize)]
185
pub struct Order {
186
    pub customer_id: u32,
187
    pub product_ids: Vec<u32>,
188
}
189

            
190
impl Order {
191
1008
    pub fn fake<R: Rng>(
192
1008
        rng: &mut R,
193
1008
        available_customers: &[u32],
194
1008
        available_products: &[u32],
195
1008
    ) -> Self {
196
1008
        let mut available_product_ids = available_products.to_vec();
197
1008
        let number_of_products = if available_product_ids.is_empty() {
198
            0
199
        } else {
200
1008
            rng.gen_range(0..((available_product_ids.len() + 2) / 3).min(20))
201
        };
202
1008
        let mut product_ids = Vec::with_capacity(number_of_products);
203
9112
        for _ in 0..number_of_products {
204
9112
            let product_index = rng.gen_range(0..available_product_ids.len());
205
9112
            product_ids.push(available_product_ids.remove(product_index));
206
9112
        }
207

            
208
1008
        Self {
209
1008
            customer_id: *available_customers.choose(rng).unwrap(),
210
1008
            product_ids,
211
1008
        }
212
1008
    }
213
}
214

            
215
25540
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
216
pub struct Cart {
217
    pub customer_id: Option<u32>,
218
    pub product_ids: Vec<u32>,
219
}
220

            
221
20880
#[derive(Clone, Debug, Serialize, Deserialize)]
222
pub struct ProductReview {
223
    pub customer_id: u32,
224
    pub product_id: u32,
225
    pub rating: u8,
226
    pub review: Option<String>,
227
}
228

            
229
impl ProductReview {
230
487
    pub fn fake<R: Rng>(
231
487
        rng: &mut R,
232
487
        available_customer_products: &HashSet<(u32, u32)>,
233
487
        already_rated: &mut HashSet<(u32, u32)>,
234
487
    ) -> Option<Self> {
235
487
        if available_customer_products.len() > already_rated.len() {
236
506
            for (customer_id, product_id) in available_customer_products
237
487
                .iter()
238
487
                .chain(available_customer_products.iter())
239
487
                .skip(rng.gen_range(0..available_customer_products.len()))
240
487
                .take(available_customer_products.len())
241
487
                .copied()
242
            {
243
506
                if already_rated.insert((customer_id, product_id)) {
244
                    return Some(Self {
245
487
                        customer_id,
246
487
                        product_id,
247
487
                        rating: rng.gen_range(1..=5),
248
487
                        review: if rng.gen_bool(0.25) {
249
151
                            Some(
250
151
                                Vec::<String>::dummy_with_rng(&Paragraphs(EN, 1..5), rng)
251
151
                                    .join("\n\n"),
252
151
                            )
253
                        } else {
254
336
                            None
255
                        },
256
                    });
257
19
                }
258
            }
259
        }
260

            
261
        None
262
487
    }
263
}