1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct User {
10 #[serde(default = "Uuid::new_v4")]
11 pub id: Uuid,
12 pub username: String,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub email: Option<String>,
15 pub password_hash: String,
16 #[serde(default = "Utc::now", with = "crate::datetime_compat")]
17 pub created_at: DateTime<Utc>,
18 #[serde(default = "Utc::now", with = "crate::datetime_compat")]
19 pub updated_at: DateTime<Utc>,
20 #[serde(default = "default_role")]
21 pub role: String,
22}
23
24fn default_role() -> String {
25 "user".to_string()
26}
27
28impl User {
29 pub fn new(username: String, password_hash: String) -> Self {
31 Self {
32 id: Uuid::new_v4(),
33 username,
34 email: None,
35 password_hash,
36 created_at: Utc::now(),
37 updated_at: Utc::now(),
38 role: "user".to_string(),
39 }
40 }
41
42 pub fn touch(&mut self) {
44 self.updated_at = Utc::now();
45 }
46}
47
48#[cfg(test)]
49#[path = "user_tests.rs"]
50mod tests;