use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[cfg(feature = "openapi")]
use utoipa::ToSchema;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
pub struct Metadata {
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deleted_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_by: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_by: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deleted_by: Option<Uuid>,
}
impl Metadata {
pub fn new(
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
deleted_at: Option<DateTime<Utc>>,
created_by: Option<Uuid>,
updated_by: Option<Uuid>,
deleted_by: Option<Uuid>,
) -> Self {
Self {
created_at,
updated_at,
deleted_at,
created_by,
updated_by,
deleted_by,
}
}
pub fn new_record(created_by: Option<Uuid>) -> Self {
let now = Utc::now();
Self {
created_at: now,
updated_at: now,
deleted_at: None,
created_by,
updated_by: None,
deleted_by: None,
}
}
pub fn mark_updated(&mut self, updated_by: Option<Uuid>) {
self.updated_at = Utc::now();
self.updated_by = updated_by;
}
pub fn mark_deleted(&mut self, deleted_by: Option<Uuid>) {
self.deleted_at = Some(Utc::now());
self.deleted_by = deleted_by;
}
pub fn is_deleted(&self) -> bool {
self.deleted_at.is_some()
}
pub fn builder() -> MetadataBuilder {
<MetadataBuilder as Default>::default()
}
pub fn to_json_value(&self) -> Result<serde_json::Value, serde_json::Error> {
serde_json::to_value(self)
}
pub fn from_json_value(value: serde_json::Value) -> Result<Self, serde_json::Error> {
serde_json::from_value(value)
}
}
#[derive(Debug, Clone, Default)]
pub struct MetadataBuilder {
created_at: Option<DateTime<Utc>>,
updated_at: Option<DateTime<Utc>>,
deleted_at: Option<DateTime<Utc>>,
created_by: Option<Uuid>,
updated_by: Option<Uuid>,
deleted_by: Option<Uuid>,
}
impl MetadataBuilder {
pub fn created_at(mut self, value: DateTime<Utc>) -> Self {
self.created_at = Some(value);
self
}
pub fn updated_at(mut self, value: DateTime<Utc>) -> Self {
self.updated_at = Some(value);
self
}
pub fn deleted_at(mut self, value: DateTime<Utc>) -> Self {
self.deleted_at = Some(value);
self
}
pub fn created_by(mut self, value: Uuid) -> Self {
self.created_by = Some(value);
self
}
pub fn updated_by(mut self, value: Uuid) -> Self {
self.updated_by = Some(value);
self
}
pub fn deleted_by(mut self, value: Uuid) -> Self {
self.deleted_by = Some(value);
self
}
pub fn no_created_by(mut self) -> Self {
self.created_by = None;
self
}
pub fn no_updated_by(mut self) -> Self {
self.updated_by = None;
self
}
pub fn no_deleted_by(mut self) -> Self {
self.deleted_by = None;
self
}
pub fn build(self) -> Result<Metadata, String> {
let created_at = self.created_at.ok_or_else(|| "created_at is required".to_string())?;
let updated_at = self.updated_at.ok_or_else(|| "updated_at is required".to_string())?;
Ok(Metadata {
created_at,
updated_at,
deleted_at: self.deleted_at,
created_by: self.created_by,
updated_by: self.updated_by,
deleted_by: self.deleted_by,
})
}
}