Restructure crates for correct proc macro usage
Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::borrow::Borrow;
|
||||
|
||||
use crate::models::{Index, Model};
|
||||
use heromodels_core::{Index, Model};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub mod fjall;
|
||||
|
@@ -1,8 +1,7 @@
|
||||
use heromodels_core::{Index, Model};
|
||||
use ourdb::OurDBSetArgs;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::models::{Index, Model};
|
||||
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
collections::HashSet,
|
||||
@@ -30,7 +29,7 @@ impl OurDB {
|
||||
impl super::Db for OurDB {
|
||||
type Error = tst::Error;
|
||||
|
||||
fn collection<M: crate::models::Model>(
|
||||
fn collection<M: Model>(
|
||||
&self,
|
||||
) -> Result<impl super::Collection<&str, M>, super::Error<Self::Error>> {
|
||||
Ok(self.clone())
|
||||
|
@@ -1,10 +1,13 @@
|
||||
use heromodels_core::BaseModelData;
|
||||
use heromodels_derive::model;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::models::core::model::{Model, BaseModelData, IndexKey};
|
||||
|
||||
/// Represents a comment on a model
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[model]
|
||||
pub struct Comment {
|
||||
pub base_data: BaseModelData,
|
||||
#[index]
|
||||
pub user_id: u32,
|
||||
pub content: String,
|
||||
}
|
||||
@@ -24,34 +27,10 @@ impl Comment {
|
||||
self.user_id = id;
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
/// Set the content
|
||||
pub fn content(mut self, content: impl ToString) -> Self {
|
||||
self.content = content.to_string();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the Model trait for Comment
|
||||
impl Model for Comment {
|
||||
fn db_prefix() -> &'static str {
|
||||
"comment"
|
||||
}
|
||||
|
||||
fn get_id(&self) -> u32 {
|
||||
self.base_data.id
|
||||
}
|
||||
|
||||
fn base_data_mut(&mut self) -> &mut BaseModelData {
|
||||
&mut self.base_data
|
||||
}
|
||||
|
||||
fn db_keys(&self) -> Vec<IndexKey> {
|
||||
vec![
|
||||
IndexKey {
|
||||
name: "user_id",
|
||||
value: self.user_id.to_string(),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// Export submodules
|
||||
pub mod model;
|
||||
pub mod comment;
|
||||
pub mod model;
|
||||
|
||||
// Re-export key types for convenience
|
||||
pub use model::{Model, BaseModelData, IndexKey, IndexKeyBuilder, Index};
|
||||
pub use comment::Comment;
|
||||
pub use comment::Comment;
|
||||
|
||||
|
@@ -1,223 +0,0 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro to implement Model for a struct that contains a base_data field of type BaseModelData
|
||||
#[macro_export]
|
||||
macro_rules! impl_model {
|
||||
// Basic implementation with default db_keys
|
||||
($type:ty, $prefix:expr) => {
|
||||
impl $crate::core::model::Model for $type {
|
||||
fn db_prefix() -> &'static str {
|
||||
$prefix
|
||||
}
|
||||
|
||||
fn get_id(&self) -> u32 {
|
||||
self.base_data.id
|
||||
}
|
||||
|
||||
fn base_data_mut(&mut self) -> &mut $crate::core::model::BaseModelData {
|
||||
&mut self.base_data
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,6 @@ pub mod core;
|
||||
pub mod userexample;
|
||||
|
||||
// Re-export key types for convenience
|
||||
pub use core::model::{Model, BaseModelData, IndexKey, Index};
|
||||
pub use core::Comment;
|
||||
pub use userexample::User;
|
||||
pub use userexample::User;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use crate::models::core::model::BaseModelData;
|
||||
use heromodels_core::BaseModelData;
|
||||
use heromodels_derive::model;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -81,72 +81,3 @@ impl User {
|
||||
self.is_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the Model trait for User
|
||||
// impl Model for User {
|
||||
// fn db_prefix() -> &'static str {
|
||||
// "user"
|
||||
// }
|
||||
//
|
||||
// fn get_id(&self) -> u32 {
|
||||
// self.base_data.id
|
||||
// }
|
||||
//
|
||||
// //WHY?
|
||||
// fn base_data_mut(&mut self) -> &mut BaseModelData {
|
||||
// &mut self.base_data
|
||||
// }
|
||||
//
|
||||
// fn db_keys(&self) -> Vec<IndexKey> {
|
||||
// vec![
|
||||
// IndexKey {
|
||||
// name: "username",
|
||||
// value: self.username.clone(),
|
||||
// },
|
||||
// IndexKey {
|
||||
// name: "email",
|
||||
// value: self.email.clone(),
|
||||
// },
|
||||
// IndexKey {
|
||||
// name: "is_active",
|
||||
// value: self.is_active.to_string(),
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Marker structs for indexed fields
|
||||
//
|
||||
// pub struct UserName;
|
||||
// pub struct Email;
|
||||
// pub struct IsActive;
|
||||
//
|
||||
// impl Index for UserName {
|
||||
// type Model = User;
|
||||
//
|
||||
// type Key = str;
|
||||
//
|
||||
// fn key() -> &'static str {
|
||||
// "username"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl Index for Email {
|
||||
// type Model = User;
|
||||
//
|
||||
// type Key = str;
|
||||
//
|
||||
// fn key() -> &'static str {
|
||||
// "email"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl Index for IsActive {
|
||||
// type Model = User;
|
||||
//
|
||||
// type Key = bool;
|
||||
//
|
||||
// fn key() -> &'static str {
|
||||
// "is_active"
|
||||
// }
|
||||
// }
|
||||
|
Reference in New Issue
Block a user