shared/domain/user_role/
model.rs1use chrono::DateTime;
2use mongodb::bson::Bson;
3use serde::{Deserialize, Serialize};
4use sqlx::FromRow;
5use utoipa::ToSchema;
6
7use crate::domain::query::IntoBsonDocument;
8
9use super::super::serde::{
10 deserialize_datetime, deserialize_object_id, deserialize_object_id_as_string,
11 serialize_object_id_as_string,
12};
13
14#[derive(Default, Debug, Clone, PartialEq, Eq, Deserialize, Serialize, FromRow, ToSchema)]
15#[schema(example = json!({ "userId": String::default(), "roleId": String::default() }))]
16pub struct UserRole {
17 #[serde(
18 rename = "_id",
19 default,
20 skip_serializing_if = "Option::is_none",
21 deserialize_with = "deserialize_object_id_as_string"
22 )]
23 pub id: Option<String>,
24
25 #[sqlx(rename = "userId")]
26 #[serde(
27 rename = "userId",
28 default,
29 serialize_with = "serialize_object_id_as_string",
30 deserialize_with = "deserialize_object_id"
31 )]
32 pub user_id: String,
33
34 #[sqlx(rename = "roleId")]
35 #[serde(
36 rename = "roleId",
37 default,
38 serialize_with = "serialize_object_id_as_string",
39 deserialize_with = "deserialize_object_id"
40 )]
41 pub role_id: String,
42
43 #[sqlx(rename = "issuedAt")]
44 #[serde(rename = "issuedAt", deserialize_with = "deserialize_datetime")]
45 pub issued_at: chrono::DateTime<chrono::Utc>,
46}
47
48impl UserRole {
49 pub fn new(user_id: &str, role_id: &str) -> Self {
50 Self {
51 id: None,
52 user_id: user_id.into(),
53 role_id: role_id.into(),
54 issued_at: chrono::Utc::now(),
55 }
56 }
57}
58
59impl IntoBsonDocument for UserRole {
60 fn into_bson_document(self) -> Result<mongodb::bson::Document, mongodb::bson::ser::Error> {
61 let mut doc = mongodb::bson::to_document(&self)?;
62
63 for key in &["issuedAt"] {
64 if let Some(Bson::String(s)) = doc.get(*key).cloned()
65 && let Ok(dt) = DateTime::parse_from_rfc3339(&s)
66 {
67 doc.insert(
68 *key,
69 mongodb::bson::Bson::DateTime(mongodb::bson::DateTime::from_millis(
70 dt.timestamp_millis(),
71 )),
72 );
73 }
74 }
75
76 Ok(doc)
77 }
78}