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
797
        for customer_id in 0..gen_range(rng, self.number_of_customers.clone()) {
43
797
            let customer = Customer::fake(rng, &customer_names);
44
797
            customer_names.insert(customer.name.clone());
45
797
            data.customers.insert(customer_id, customer);
46
797
        }
47
51
        for category_id in 0..gen_range(rng, self.number_of_categories.clone()) {
48
51
            data.categories.insert(category_id, Category::fake(rng));
49
51
        }
50
4
        let mut product_names = HashSet::new();
51
338
        for product_id in 0..gen_range(rng, self.number_of_products.clone()) {
52
338
            let product = Product::fake(rng, &data.categories, &product_names);
53
338
            product_names.insert(product.name.clone());
54
338
            data.products.insert(product_id, product);
55
338
        }
56
4
        let customer_ids = data.customers.keys().copied().collect::<Vec<_>>();
57
4
        let product_ids = data.products.keys().copied().collect::<Vec<_>>();
58
845
        for order_id in 0..gen_range(rng, self.number_of_orders.clone()) {
59
845
            data.orders
60
845
                .insert(order_id, Order::fake(rng, &customer_ids, &product_ids));
61
845
        }
62
4
        let products_available_to_rate = data
63
4
            .orders
64
4
            .values()
65
845
            .flat_map(|order| {
66
845
                order
67
845
                    .product_ids
68
845
                    .iter()
69
6051
                    .map(|&product_id| (order.customer_id, product_id))
70
845
            })
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
334
                if let Some(review) =
76
334
                    ProductReview::fake(rng, &products_available_to_rate, &mut rated_products)
77
334
                {
78
334
                    data.reviews.push(review);
79
334
                }
80
            }
81
        }
82

            
83
4
        data
84
4
    }
85
}
86

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

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

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

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

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

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

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

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

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

            
215
26320
#[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
15840
#[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
334
    pub fn fake<R: Rng>(
231
334
        rng: &mut R,
232
334
        available_customer_products: &HashSet<(u32, u32)>,
233
334
        already_rated: &mut HashSet<(u32, u32)>,
234
334
    ) -> Option<Self> {
235
334
        if available_customer_products.len() > already_rated.len() {
236
350
            for (customer_id, product_id) in available_customer_products
237
334
                .iter()
238
334
                .chain(available_customer_products.iter())
239
334
                .skip(rng.gen_range(0..available_customer_products.len()))
240
334
                .take(available_customer_products.len())
241
334
                .copied()
242
            {
243
350
                if already_rated.insert((customer_id, product_id)) {
244
                    return Some(Self {
245
334
                        customer_id,
246
334
                        product_id,
247
334
                        rating: rng.gen_range(1..=5),
248
334
                        review: if rng.gen_bool(0.25) {
249
94
                            Some(
250
94
                                Vec::<String>::dummy_with_rng(&Paragraphs(EN, 1..5), rng)
251
94
                                    .join("\n\n"),
252
94
                            )
253
                        } else {
254
240
                            None
255
                        },
256
                    });
257
16
                }
258
            }
259
        }
260

            
261
        None
262
334
    }
263
}