45 lines
1.3 KiB
Rust
45 lines
1.3 KiB
Rust
use chrono::{DateTime, Utc};
|
|
use sqlx::FromRow;
|
|
use uuid::Uuid;
|
|
|
|
use domain::{DomainError, Email, User};
|
|
|
|
#[derive(Debug, FromRow)]
|
|
pub(super) struct UserRow {
|
|
pub id: String,
|
|
pub subject: String,
|
|
pub email: String,
|
|
pub password_hash: Option<String>,
|
|
pub is_admin: i64,
|
|
pub created_at: String,
|
|
}
|
|
|
|
impl TryFrom<UserRow> for User {
|
|
type Error = DomainError;
|
|
|
|
fn try_from(row: UserRow) -> Result<Self, Self::Error> {
|
|
let id = Uuid::parse_str(&row.id)
|
|
.map_err(|e| DomainError::RepositoryError(format!("Invalid UUID: {}", e)))?;
|
|
let created_at = DateTime::parse_from_rfc3339(&row.created_at)
|
|
.map(|dt| dt.with_timezone(&Utc))
|
|
.or_else(|_| {
|
|
// Fallback for SQLite datetime format
|
|
chrono::NaiveDateTime::parse_from_str(&row.created_at, "%Y-%m-%d %H:%M:%S")
|
|
.map(|dt| dt.and_utc())
|
|
})
|
|
.map_err(|e| DomainError::RepositoryError(format!("Invalid datetime: {}", e)))?;
|
|
|
|
let email = Email::try_from(row.email)
|
|
.map_err(|e| DomainError::RepositoryError(format!("Invalid email in DB: {}", e)))?;
|
|
|
|
Ok(User::with_id(
|
|
id,
|
|
row.subject,
|
|
email,
|
|
row.password_hash,
|
|
row.is_admin != 0,
|
|
created_at,
|
|
))
|
|
}
|
|
}
|