Restructure crates for correct proc macro usage
Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
		
							
								
								
									
										201
									
								
								heromodels_core/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								heromodels_core/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
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,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user