mostro_core/
user.rs

1use chrono::Utc;
2use serde::{Deserialize, Serialize};
3#[cfg(feature = "sqlx")]
4use sqlx::FromRow;
5
6#[derive(Debug, Default, Deserialize, Serialize, Clone)]
7
8pub struct UserInfo {
9    /// User's rating
10    pub rating: f64,
11    /// User's total reviews
12    pub reviews: i64,
13    /// User's operating days
14    pub operating_days: u64,
15}
16
17/// Database representation of an user
18#[cfg_attr(feature = "sqlx", derive(FromRow))]
19#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
20pub struct User {
21    pub pubkey: String,
22    pub is_admin: i64,
23    pub admin_password: Option<String>,
24    pub is_solver: i64,
25    pub is_banned: i64,
26    pub category: i64,
27    /// We have to be sure that when a user creates a new order (or takes an order),
28    /// the trade_index is greater than the one we have in database
29    pub last_trade_index: i64,
30    pub total_reviews: i64,
31    pub total_rating: f64,
32    pub last_rating: i64,
33    pub max_rating: i64,
34    pub min_rating: i64,
35    pub created_at: i64,
36}
37
38impl User {
39    pub fn new(
40        pubkey: String,
41        is_admin: i64,
42        is_solver: i64,
43        is_banned: i64,
44        category: i64,
45        trade_index: i64,
46    ) -> Self {
47        Self {
48            pubkey,
49            is_admin,
50            admin_password: None,
51            is_solver,
52            is_banned,
53            category,
54            last_trade_index: trade_index,
55            total_reviews: 0,
56            total_rating: 0.0,
57            last_rating: 0,
58            max_rating: 0,
59            min_rating: 0,
60            created_at: Utc::now().timestamp(),
61        }
62    }
63
64    /// Update user rating
65    pub fn update_rating(&mut self, rating: u8) {
66        // Update user reputation
67        // increment first
68        self.total_reviews += 1;
69        let old_rating = self.total_rating;
70        // recompute new rating
71        if self.total_reviews <= 1 {
72            // New logic with weight 1/2 for first vote.
73            let first_rating = rating as f64;
74            self.total_rating = first_rating / 2.0;
75            self.max_rating = rating.into();
76            self.min_rating = rating.into();
77        } else {
78            self.total_rating =
79                old_rating + ((self.last_rating as f64) - old_rating) / (self.total_reviews as f64);
80            if self.max_rating < rating.into() {
81                self.max_rating = rating.into();
82            }
83            if self.min_rating > rating.into() {
84                self.min_rating = rating.into();
85            }
86        }
87        // Store last rating
88        self.last_rating = rating.into();
89    }
90}