202 lines
4.9 KiB
Rust
202 lines
4.9 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use std::fmt::Debug;
|
|
|
|
/// Represents an index key for a model
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct IndexKey {
|
|
/// The name of the index key
|
|
pub name: &'static str,
|
|
|
|
/// The value of the index key for a specific model instance
|
|
pub value: String,
|
|
}
|
|
|
|
/// Builder for IndexKey
|
|
pub struct IndexKeyBuilder {
|
|
name: &'static str,
|
|
value: String,
|
|
}
|
|
|
|
impl IndexKeyBuilder {
|
|
/// Create a new IndexKeyBuilder
|
|
pub fn new(name: &'static str) -> Self {
|
|
Self {
|
|
name,
|
|
value: String::new(),
|
|
}
|
|
}
|
|
|
|
/// Set the value for this index key
|
|
pub fn value(mut self, value: impl ToString) -> Self {
|
|
self.value = value.to_string();
|
|
self
|
|
}
|
|
|
|
/// Build the IndexKey
|
|
pub fn build(self) -> IndexKey {
|
|
IndexKey {
|
|
name: self.name,
|
|
value: self.value,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Unified trait for all models
|
|
pub trait Model:
|
|
Debug + Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static
|
|
{
|
|
/// Get the database prefix for this model type
|
|
fn db_prefix() -> &'static str
|
|
where
|
|
Self: Sized;
|
|
|
|
/// Returns a list of index keys for this model instance
|
|
/// These keys will be used to create additional indexes in the TST
|
|
/// The default implementation returns an empty vector
|
|
/// Override this method to provide custom indexes
|
|
fn db_keys(&self) -> Vec<IndexKey> {
|
|
Vec::new()
|
|
}
|
|
|
|
/// Get the unique ID for this model
|
|
fn get_id(&self) -> u32;
|
|
|
|
/// Get a mutable reference to the base_data field
|
|
fn base_data_mut(&mut self) -> &mut BaseModelData;
|
|
|
|
/// Set the ID for this model
|
|
fn id(mut self, id: u32) -> Self
|
|
where
|
|
Self: Sized,
|
|
{
|
|
self.base_data_mut().id = id;
|
|
self
|
|
}
|
|
|
|
/// Build the model, updating the modified timestamp
|
|
fn build(mut self) -> Self
|
|
where
|
|
Self: Sized,
|
|
{
|
|
self.base_data_mut().update_modified();
|
|
self
|
|
}
|
|
}
|
|
|
|
/// An identifier for an index in the DB
|
|
pub trait Index {
|
|
/// The model for which this is an index in the database
|
|
type Model: Model;
|
|
|
|
type Key: ToString + ?Sized;
|
|
|
|
/// The key of this index
|
|
fn key() -> &'static str;
|
|
}
|
|
|
|
/// Base struct that all models should include
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct BaseModelData {
|
|
/// Unique incremental ID per circle
|
|
pub id: u32,
|
|
|
|
/// Unix epoch timestamp for creation time
|
|
pub created_at: i64,
|
|
|
|
/// Unix epoch timestamp for last modification time
|
|
pub modified_at: i64,
|
|
|
|
/// List of comment IDs referencing Comment objects
|
|
pub comments: Vec<u32>,
|
|
}
|
|
|
|
impl BaseModelData {
|
|
/// Create a new BaseModelData instance
|
|
pub fn new(id: u32) -> Self {
|
|
let now = chrono::Utc::now().timestamp();
|
|
Self {
|
|
id,
|
|
created_at: now,
|
|
modified_at: now,
|
|
comments: Vec::new(),
|
|
}
|
|
}
|
|
|
|
/// Create a new BaseModelDataBuilder
|
|
pub fn builder(id: u32) -> BaseModelDataBuilder {
|
|
BaseModelDataBuilder::new(id)
|
|
}
|
|
|
|
/// Add a comment to this model
|
|
pub fn add_comment(&mut self, comment_id: u32) {
|
|
self.comments.push(comment_id);
|
|
self.modified_at = chrono::Utc::now().timestamp();
|
|
}
|
|
|
|
/// Remove a comment from this model
|
|
pub fn remove_comment(&mut self, comment_id: u32) {
|
|
self.comments.retain(|&id| id != comment_id);
|
|
self.update_modified();
|
|
}
|
|
|
|
/// Update the modified timestamp
|
|
pub fn update_modified(&mut self) {
|
|
self.modified_at = chrono::Utc::now().timestamp();
|
|
}
|
|
}
|
|
|
|
/// Builder for BaseModelData
|
|
pub struct BaseModelDataBuilder {
|
|
id: u32,
|
|
created_at: Option<i64>,
|
|
modified_at: Option<i64>,
|
|
comments: Vec<u32>,
|
|
}
|
|
|
|
impl BaseModelDataBuilder {
|
|
/// Create a new BaseModelDataBuilder
|
|
pub fn new(id: u32) -> Self {
|
|
Self {
|
|
id,
|
|
created_at: None,
|
|
modified_at: None,
|
|
comments: Vec::new(),
|
|
}
|
|
}
|
|
|
|
/// Set the created_at timestamp
|
|
pub fn created_at(mut self, timestamp: i64) -> Self {
|
|
self.created_at = Some(timestamp);
|
|
self
|
|
}
|
|
|
|
/// Set the modified_at timestamp
|
|
pub fn modified_at(mut self, timestamp: i64) -> Self {
|
|
self.modified_at = Some(timestamp);
|
|
self
|
|
}
|
|
|
|
/// Add a comment ID
|
|
pub fn add_comment(mut self, comment_id: u32) -> Self {
|
|
self.comments.push(comment_id);
|
|
self
|
|
}
|
|
|
|
/// Add multiple comment IDs
|
|
pub fn add_comments(mut self, comment_ids: Vec<u32>) -> Self {
|
|
self.comments.extend(comment_ids);
|
|
self
|
|
}
|
|
|
|
/// Build the BaseModelData
|
|
pub fn build(self) -> BaseModelData {
|
|
let now = chrono::Utc::now().timestamp();
|
|
BaseModelData {
|
|
id: self.id,
|
|
created_at: self.created_at.unwrap_or(now),
|
|
modified_at: self.modified_at.unwrap_or(now),
|
|
comments: self.comments,
|
|
}
|
|
}
|
|
}
|