db new models
This commit is contained in:
		
							
								
								
									
										58
									
								
								heromodels/src/models/access/access.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								heromodels/src/models/access/access.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
use heromodels_core::BaseModelData;
 | 
			
		||||
use heromodels_derive::model;
 | 
			
		||||
// Temporarily removed to fix compilation issues
 | 
			
		||||
// use rhai_autobind_macros::rhai_model_export;
 | 
			
		||||
use rhai::{CustomType, TypeBuilder};
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
/// Represents an event in a contact
 | 
			
		||||
#[model]
 | 
			
		||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
 | 
			
		||||
pub struct Access {
 | 
			
		||||
    /// Base model data
 | 
			
		||||
    pub base_data: BaseModelData,
 | 
			
		||||
    #[index]
 | 
			
		||||
    pub object_id: u32,
 | 
			
		||||
    pub circle_id: u32,
 | 
			
		||||
    pub contact_id: u32,
 | 
			
		||||
    pub group_id: u32,
 | 
			
		||||
    pub expires_at: Option<u64>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Access {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        Access {
 | 
			
		||||
            base_data: BaseModelData::new(),
 | 
			
		||||
            object_id: 0,
 | 
			
		||||
            circle_id: 0,
 | 
			
		||||
            contact_id: 0,
 | 
			
		||||
            group_id: 0,
 | 
			
		||||
            expires_at: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn object_id(mut self, object_id: u32) -> Self {
 | 
			
		||||
        self.object_id = object_id;
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn contact_id(mut self, contact_id: u32) -> Self {
 | 
			
		||||
        self.contact_id = contact_id;
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn group_id(mut self, group_id: u32) -> Self {
 | 
			
		||||
        self.group_id = group_id;
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn circle_id(mut self, circle_id: u32) -> Self {
 | 
			
		||||
        self.circle_id = circle_id;
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn expires_at(mut self, expires_at: Option<u64>) -> Self {
 | 
			
		||||
        self.expires_at = expires_at;
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								heromodels/src/models/access/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								heromodels/src/models/access/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// Export contact module
 | 
			
		||||
pub mod access;
 | 
			
		||||
pub mod rhai;
 | 
			
		||||
 | 
			
		||||
// Re-export contact, Group from the inner contact module (contact.rs) within src/models/contact/mod.rs
 | 
			
		||||
pub use self::access::{Access};
 | 
			
		||||
pub use rhai::register_access_rhai_module;
 | 
			
		||||
							
								
								
									
										177
									
								
								heromodels/src/models/access/rhai.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								heromodels/src/models/access/rhai.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
use rhai::plugin::*;
 | 
			
		||||
use rhai::{Engine, EvalAltResult, Position, Module, INT, Dynamic, Array};
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use std::mem;
 | 
			
		||||
use crate::db::Db;
 | 
			
		||||
 | 
			
		||||
use super::access::{Access};
 | 
			
		||||
type RhaiAccess = Access;
 | 
			
		||||
use crate::db::hero::OurDB;
 | 
			
		||||
use crate::db::Collection;
 | 
			
		||||
 | 
			
		||||
// Helper to convert i64 from Rhai to u32 for IDs
 | 
			
		||||
fn id_from_i64_to_u32(id_i64: i64) -> Result<u32, Box<EvalAltResult>> {
 | 
			
		||||
    u32::try_from(id_i64).map_err(|_|
 | 
			
		||||
        Box::new(EvalAltResult::ErrorArithmetic(
 | 
			
		||||
            format!("Failed to convert ID '{}' to u32", id_i64).into(),
 | 
			
		||||
            Position::NONE
 | 
			
		||||
        ))
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[export_module]
 | 
			
		||||
mod rhai_access_module {
 | 
			
		||||
    // --- Access Functions ---
 | 
			
		||||
    #[rhai_fn(name = "new_access", return_raw)]
 | 
			
		||||
    pub fn new_access() -> Result<RhaiAccess, Box<EvalAltResult>> {
 | 
			
		||||
        let access = Access::new();
 | 
			
		||||
        Ok(access)
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Sets the access name
 | 
			
		||||
    #[rhai_fn(name = "object_id", return_raw, global, pure)]
 | 
			
		||||
    pub fn access_object_id(access: &mut RhaiAccess, object_id: u32) -> Result<RhaiAccess, Box<EvalAltResult>> {
 | 
			
		||||
        // Create a default Access to replace the taken one
 | 
			
		||||
        let default_access = Access::new();
 | 
			
		||||
        
 | 
			
		||||
        // Take ownership of the access, apply the builder method, then put it back
 | 
			
		||||
        let owned_access = std::mem::replace(access, default_access);
 | 
			
		||||
        *access = owned_access.object_id(object_id);
 | 
			
		||||
        Ok(access.clone())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(name = "circle_id", return_raw, global, pure)]
 | 
			
		||||
    pub fn access_circle_id(access: &mut RhaiAccess, circle_id: u32) -> Result<RhaiAccess, Box<EvalAltResult>> {
 | 
			
		||||
        // Create a default Access to replace the taken one
 | 
			
		||||
        let default_access = Access::new();
 | 
			
		||||
        
 | 
			
		||||
        // Take ownership of the access, apply the builder method, then put it back
 | 
			
		||||
        let owned_access = std::mem::replace(access, default_access);
 | 
			
		||||
        *access = owned_access.circle_id(circle_id);
 | 
			
		||||
        Ok(access.clone())
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[rhai_fn(name = "group_id", return_raw, global, pure)]
 | 
			
		||||
    pub fn access_group_id(access: &mut RhaiAccess, group_id: u32) -> Result<RhaiAccess, Box<EvalAltResult>> {
 | 
			
		||||
        // Create a default Access to replace the taken one
 | 
			
		||||
        let default_access = Access::new();
 | 
			
		||||
        
 | 
			
		||||
        // Take ownership of the access, apply the builder method, then put it back
 | 
			
		||||
        let owned_access = std::mem::replace(access, default_access);
 | 
			
		||||
        *access = owned_access.group_id(group_id);
 | 
			
		||||
        Ok(access.clone())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(name = "contact_id", return_raw, global, pure)]
 | 
			
		||||
    pub fn access_contact_id(access: &mut RhaiAccess, contact_id: u32) -> Result<RhaiAccess, Box<EvalAltResult>> {
 | 
			
		||||
        // Create a default Access to replace the taken one
 | 
			
		||||
        let default_access = Access::new();
 | 
			
		||||
        
 | 
			
		||||
        // Take ownership of the access, apply the builder method, then put it back
 | 
			
		||||
        let owned_access = std::mem::replace(access, default_access);
 | 
			
		||||
        *access = owned_access.contact_id(contact_id);
 | 
			
		||||
        Ok(access.clone())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(name = "expires_at", return_raw, global, pure)]
 | 
			
		||||
    pub fn access_expires_at(access: &mut RhaiAccess, expires_at: Option<u64>) -> Result<RhaiAccess, Box<EvalAltResult>> {
 | 
			
		||||
        // Create a default Access to replace the taken one
 | 
			
		||||
        let default_access = Access::new();
 | 
			
		||||
        
 | 
			
		||||
        // Take ownership of the access, apply the builder method, then put it back
 | 
			
		||||
        let owned_access = std::mem::replace(access, default_access);
 | 
			
		||||
        *access = owned_access.expires_at(expires_at);
 | 
			
		||||
        Ok(access.clone())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Access Getters
 | 
			
		||||
    #[rhai_fn(get = "id", pure)]
 | 
			
		||||
    pub fn get_access_id(access: &mut RhaiAccess) -> i64 { access.base_data.id as i64 }
 | 
			
		||||
    
 | 
			
		||||
    #[rhai_fn(get = "object_id", pure)]
 | 
			
		||||
    pub fn get_access_object_id(access: &mut RhaiAccess) -> i64 { access.object_id as i64 }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(get = "circle_id", pure)]
 | 
			
		||||
    pub fn get_access_circle_id(access: &mut RhaiAccess) -> i64 { access.circle_id as i64 }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(get = "group_id", pure)]
 | 
			
		||||
    pub fn get_access_group_id(access: &mut RhaiAccess) -> i64 { access.group_id as i64 }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(get = "contact_id", pure)]
 | 
			
		||||
    pub fn get_access_contact_id(access: &mut RhaiAccess) -> i64 { access.contact_id as i64 }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(get = "expires_at", pure)]
 | 
			
		||||
    pub fn get_access_expires_at(access: &mut RhaiAccess) -> i64 { access.expires_at.unwrap_or(0) as i64 }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(get = "created_at", pure)]
 | 
			
		||||
    pub fn get_access_created_at(access: &mut RhaiAccess) -> i64 { access.base_data.created_at }
 | 
			
		||||
    
 | 
			
		||||
    #[rhai_fn(get = "modified_at", pure)]
 | 
			
		||||
    pub fn get_access_modified_at(access: &mut RhaiAccess) -> i64 { access.base_data.modified_at }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn register_access_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
 | 
			
		||||
    // Register the exported module globally
 | 
			
		||||
    let module = exported_module!(rhai_access_module);
 | 
			
		||||
    engine.register_global_module(module.into());
 | 
			
		||||
    
 | 
			
		||||
    // Create a module for database functions
 | 
			
		||||
    let mut db_module = Module::new();
 | 
			
		||||
    
 | 
			
		||||
    let db_clone_set_access = db.clone();
 | 
			
		||||
    db_module.set_native_fn("save_access", move |access: Access| -> Result<Access, Box<EvalAltResult>> {
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        let result = db_clone_set_access.set(&access)
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error set_access: {}", e).into(), Position::NONE)))?;
 | 
			
		||||
        
 | 
			
		||||
        // Return the updated access with the correct ID
 | 
			
		||||
        Ok(result.1)
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Manually register database functions as they need to capture 'db'
 | 
			
		||||
    let db_clone_delete_access = db.clone();
 | 
			
		||||
    db_module.set_native_fn("delete_access", move |access: Access| -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        let result = db_clone_delete_access.collection::<Access>()
 | 
			
		||||
            .expect("can open access collection")
 | 
			
		||||
            .delete_by_id(access.base_data.id)
 | 
			
		||||
            .expect("can delete event");
 | 
			
		||||
        
 | 
			
		||||
        // Return the updated event with the correct ID
 | 
			
		||||
        Ok(result)
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    let db_clone_get_access = db.clone();
 | 
			
		||||
    db_module.set_native_fn("get_access_by_id", move |id_i64: INT| -> Result<Access, Box<EvalAltResult>> {
 | 
			
		||||
        let id_u32 = id_from_i64_to_u32(id_i64)?;
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        db_clone_get_access.get_by_id(id_u32)
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error get_access_by_id: {}", e).into(), Position::NONE)))?            
 | 
			
		||||
            .ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Access with ID {} not found", id_u32).into(), Position::NONE)))
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Add list_accesss function to get all accesss
 | 
			
		||||
    let db_clone_list_accesss = db.clone();
 | 
			
		||||
    db_module.set_native_fn("list_accesss", move || -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
        let collection = db_clone_list_accesss.collection::<Access>()
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
                format!("Failed to get access collection: {:?}", e).into(), 
 | 
			
		||||
                Position::NONE
 | 
			
		||||
            )))?;
 | 
			
		||||
        let accesss = collection.get_all()
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
                format!("Failed to get all accesss: {:?}", e).into(), 
 | 
			
		||||
                Position::NONE
 | 
			
		||||
            )))?;
 | 
			
		||||
        let mut array = Array::new();
 | 
			
		||||
        for access in accesss {
 | 
			
		||||
            array.push(Dynamic::from(access));
 | 
			
		||||
        }
 | 
			
		||||
        Ok(Dynamic::from(array))
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    // Register the database module globally
 | 
			
		||||
    engine.register_global_module(db_module.into());
 | 
			
		||||
 | 
			
		||||
    println!("Successfully registered access Rhai module using export_module approach.");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										115
									
								
								heromodels/src/models/contact/contact.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								heromodels/src/models/contact/contact.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
use heromodels_core::BaseModelData;
 | 
			
		||||
use heromodels_derive::model;
 | 
			
		||||
// Temporarily removed to fix compilation issues
 | 
			
		||||
// use rhai_autobind_macros::rhai_model_export;
 | 
			
		||||
use rhai::{CustomType, TypeBuilder};
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
/// Represents an event in a contact
 | 
			
		||||
#[model]
 | 
			
		||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
 | 
			
		||||
pub struct Contact {
 | 
			
		||||
    /// Base model data
 | 
			
		||||
    pub base_data: BaseModelData,
 | 
			
		||||
    #[index]
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub description: Option<String>,
 | 
			
		||||
    pub address: String,
 | 
			
		||||
    pub phone: String,
 | 
			
		||||
    pub email: String,
 | 
			
		||||
    pub notes: Option<String>,
 | 
			
		||||
    pub circle: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Contact {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        Contact {
 | 
			
		||||
            base_data: BaseModelData::new(),
 | 
			
		||||
            name: String::new(),
 | 
			
		||||
            description: None,
 | 
			
		||||
            address: String::new(),
 | 
			
		||||
            phone: String::new(),
 | 
			
		||||
            email: String::new(),
 | 
			
		||||
            notes: None,
 | 
			
		||||
            circle: String::new(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn name(mut self, name: impl ToString) -> Self {
 | 
			
		||||
        self.name = name.to_string();
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn description(mut self, description: impl ToString) -> Self {
 | 
			
		||||
        self.description = Some(description.to_string());
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn address(mut self, address: impl ToString) -> Self {
 | 
			
		||||
        self.address = address.to_string();
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn phone(mut self, phone: impl ToString) -> Self {
 | 
			
		||||
        self.phone = phone.to_string();
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn email(mut self, email: impl ToString) -> Self {
 | 
			
		||||
        self.email = email.to_string();
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn notes(mut self, notes: impl ToString) -> Self {
 | 
			
		||||
        self.notes = Some(notes.to_string());
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn circle(mut self, circle: impl ToString) -> Self {
 | 
			
		||||
        self.circle = circle.to_string();
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Represents an event in a contact
 | 
			
		||||
#[model]
 | 
			
		||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, CustomType)]
 | 
			
		||||
pub struct Group {
 | 
			
		||||
    /// Base model data
 | 
			
		||||
    pub base_data: BaseModelData,
 | 
			
		||||
    #[index]
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub description: Option<String>,
 | 
			
		||||
    pub contacts: Vec<u32>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Group {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        Group {
 | 
			
		||||
            base_data: BaseModelData::new(),
 | 
			
		||||
            name: String::new(),
 | 
			
		||||
            description: None,
 | 
			
		||||
            contacts: Vec::new(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn name(mut self, name: impl ToString) -> Self {
 | 
			
		||||
        self.name = name.to_string();
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn description(mut self, description: impl ToString) -> Self {
 | 
			
		||||
        self.description = Some(description.to_string());
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn contacts(mut self, contacts: Vec<u32>) -> Self {
 | 
			
		||||
        self.contacts = contacts;
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn add_contact(mut self, contact: u32) -> Self {
 | 
			
		||||
        self.contacts.push(contact);
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								heromodels/src/models/contact/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								heromodels/src/models/contact/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// Export contact module
 | 
			
		||||
pub mod contact;
 | 
			
		||||
pub mod rhai;
 | 
			
		||||
 | 
			
		||||
// Re-export contact, Group from the inner contact module (contact.rs) within src/models/contact/mod.rs
 | 
			
		||||
pub use self::contact::{Contact, Group};
 | 
			
		||||
pub use rhai::register_contact_rhai_module;
 | 
			
		||||
							
								
								
									
										235
									
								
								heromodels/src/models/contact/rhai.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								heromodels/src/models/contact/rhai.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,235 @@
 | 
			
		||||
use rhai::plugin::*;
 | 
			
		||||
use rhai::{Engine, EvalAltResult, Position, Module, INT, Dynamic, Array};
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use std::mem;
 | 
			
		||||
use crate::db::Db;
 | 
			
		||||
 | 
			
		||||
use super::contact::{Group, Contact};
 | 
			
		||||
type RhaiGroup = Group;
 | 
			
		||||
type RhaiContact = Contact;
 | 
			
		||||
use crate::db::hero::OurDB;
 | 
			
		||||
use crate::db::Collection;
 | 
			
		||||
 | 
			
		||||
// Helper to convert i64 from Rhai to u32 for IDs
 | 
			
		||||
fn id_from_i64_to_u32(id_i64: i64) -> Result<u32, Box<EvalAltResult>> {
 | 
			
		||||
    u32::try_from(id_i64).map_err(|_|
 | 
			
		||||
        Box::new(EvalAltResult::ErrorArithmetic(
 | 
			
		||||
            format!("Failed to convert ID '{}' to u32", id_i64).into(),
 | 
			
		||||
            Position::NONE
 | 
			
		||||
        ))
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[export_module]
 | 
			
		||||
mod rhai_contact_module {
 | 
			
		||||
    // --- Event Functions ---
 | 
			
		||||
    #[rhai_fn(name = "new_group")]
 | 
			
		||||
    pub fn new_group() -> RhaiGroup {
 | 
			
		||||
        Group::new()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Sets the event title
 | 
			
		||||
    #[rhai_fn(name = "name", return_raw, global, pure)]
 | 
			
		||||
    pub fn group_name(group: &mut RhaiGroup, name: String) -> Result<RhaiGroup, Box<EvalAltResult>> {
 | 
			
		||||
        let owned_group = mem::take(group);
 | 
			
		||||
        *group = owned_group.name(name);
 | 
			
		||||
        Ok(group.clone())
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Sets the event description
 | 
			
		||||
    #[rhai_fn(name = "description", return_raw, global, pure)]
 | 
			
		||||
    pub fn group_description(group: &mut RhaiGroup, description: String) -> Result<RhaiGroup, Box<EvalAltResult>> {
 | 
			
		||||
        let owned_group = mem::take(group);
 | 
			
		||||
        *group = owned_group.description(description);
 | 
			
		||||
        Ok(group.clone())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Adds an attendee to the event
 | 
			
		||||
    #[rhai_fn(name = "add_contact", return_raw, global, pure)]
 | 
			
		||||
    pub fn group_add_contact(group: &mut RhaiGroup, contact_id: i64) -> Result<RhaiGroup, Box<EvalAltResult>> {
 | 
			
		||||
        // Use take to get ownership of the event
 | 
			
		||||
        let owned_group = mem::take(group);
 | 
			
		||||
        *group = owned_group.add_contact(contact_id as u32);
 | 
			
		||||
        Ok(group.clone())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[rhai_fn(get = "contacts", pure)]
 | 
			
		||||
    pub fn get_group_contacts(group: &mut RhaiGroup) -> Vec<i64> { group.contacts.clone().into_iter().map(|id| id as i64).collect() }
 | 
			
		||||
 | 
			
		||||
    // Group Getters
 | 
			
		||||
    #[rhai_fn(get = "id", pure)]
 | 
			
		||||
    pub fn get_group_id(group: &mut RhaiGroup) -> i64 { group.base_data.id as i64 }
 | 
			
		||||
    #[rhai_fn(get = "created_at", pure)]
 | 
			
		||||
    pub fn get_group_created_at(group: &mut RhaiGroup) -> i64 { group.base_data.created_at }
 | 
			
		||||
    #[rhai_fn(get = "modified_at", pure)]
 | 
			
		||||
    pub fn get_group_modified_at(group: &mut RhaiGroup) -> i64 { group.base_data.modified_at }
 | 
			
		||||
    
 | 
			
		||||
    #[rhai_fn(get = "name", pure)]
 | 
			
		||||
    pub fn get_group_name(group: &mut RhaiGroup) -> String { group.name.clone() }
 | 
			
		||||
    #[rhai_fn(get = "description", pure)]
 | 
			
		||||
    pub fn get_group_description(group: &mut RhaiGroup) -> Option<String> { group.description.clone() }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // --- Contact Functions ---
 | 
			
		||||
    #[rhai_fn(name = "new_contact", return_raw)]
 | 
			
		||||
    pub fn new_contact() -> Result<RhaiContact, Box<EvalAltResult>> {
 | 
			
		||||
        let contact = Contact::new();
 | 
			
		||||
        Ok(contact)
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Sets the contact name
 | 
			
		||||
    #[rhai_fn(name = "name", return_raw, global, pure)]
 | 
			
		||||
    pub fn contact_name(contact: &mut RhaiContact, name: String) -> Result<RhaiContact, Box<EvalAltResult>> {
 | 
			
		||||
        // Create a default Contact to replace the taken one
 | 
			
		||||
        let default_contact = Contact::new();
 | 
			
		||||
        
 | 
			
		||||
        // Take ownership of the contact, apply the builder method, then put it back
 | 
			
		||||
        let owned_contact = std::mem::replace(contact, default_contact);
 | 
			
		||||
        *contact = owned_contact.name(name);
 | 
			
		||||
        Ok(contact.clone())
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Sets the contact description
 | 
			
		||||
    #[rhai_fn(name = "description", return_raw, global, pure)]
 | 
			
		||||
    pub fn contact_description(contact: &mut RhaiContact, description: String) -> Result<RhaiContact, Box<EvalAltResult>> {
 | 
			
		||||
        // Create a default Contact to replace the taken one
 | 
			
		||||
        let default_contact = Contact::new();
 | 
			
		||||
        
 | 
			
		||||
        // Take ownership of the contact, apply the builder method, then put it back
 | 
			
		||||
        let owned_contact = std::mem::replace(contact, default_contact);
 | 
			
		||||
        *contact = owned_contact.description(description);
 | 
			
		||||
        Ok(contact.clone())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Contact Getters
 | 
			
		||||
    #[rhai_fn(get = "id", pure)]
 | 
			
		||||
    pub fn get_contact_id(contact: &mut RhaiContact) -> i64 { contact.base_data.id as i64 }
 | 
			
		||||
    
 | 
			
		||||
    #[rhai_fn(get = "name", pure)]
 | 
			
		||||
    pub fn get_contact_name(contact: &mut RhaiContact) -> String { contact.name.clone() }
 | 
			
		||||
    
 | 
			
		||||
    #[rhai_fn(get = "created_at", pure)]
 | 
			
		||||
    pub fn get_contact_created_at(contact: &mut RhaiContact) -> i64 { contact.base_data.created_at }
 | 
			
		||||
    
 | 
			
		||||
    #[rhai_fn(get = "modified_at", pure)]
 | 
			
		||||
    pub fn get_contact_modified_at(contact: &mut RhaiContact) -> i64 { contact.base_data.modified_at }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn register_contact_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
 | 
			
		||||
    // Register the exported module globally
 | 
			
		||||
    let module = exported_module!(rhai_contact_module);
 | 
			
		||||
    engine.register_global_module(module.into());
 | 
			
		||||
    
 | 
			
		||||
    // Create a module for database functions
 | 
			
		||||
    let mut db_module = Module::new();
 | 
			
		||||
 | 
			
		||||
    // Manually register database functions as they need to capture 'db'
 | 
			
		||||
    let db_clone_set_group = db.clone();
 | 
			
		||||
    db_module.set_native_fn("save_group", move |group: Group| -> Result<Group, Box<EvalAltResult>> {
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        let result = db_clone_set_group.set(&group)
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error set_group: {}", e).into(), Position::NONE)))?;
 | 
			
		||||
        
 | 
			
		||||
        // Return the updated event with the correct ID
 | 
			
		||||
        Ok(result.1)
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Manually register database functions as they need to capture 'db'
 | 
			
		||||
    let db_clone_delete_group = db.clone();
 | 
			
		||||
    db_module.set_native_fn("delete_group", move |group: Group| -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        let result = db_clone_delete_group.collection::<Group>()
 | 
			
		||||
            .expect("can open group collection")
 | 
			
		||||
            .delete_by_id(group.base_data.id)
 | 
			
		||||
            .expect("can delete group");
 | 
			
		||||
        
 | 
			
		||||
        // Return the updated event with the correct ID
 | 
			
		||||
        Ok(result)
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    let db_clone_get_group = db.clone();
 | 
			
		||||
    db_module.set_native_fn("get_group_by_id", move |id_i64: INT| -> Result<Group, Box<EvalAltResult>> {
 | 
			
		||||
        let id_u32 = id_from_i64_to_u32(id_i64)?;
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        db_clone_get_group.get_by_id(id_u32)
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error get_event_by_id: {}", e).into(), Position::NONE)))?            
 | 
			
		||||
            .ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Event with ID {} not found", id_u32).into(), Position::NONE)))
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    let db_clone_set_contact = db.clone();
 | 
			
		||||
    db_module.set_native_fn("save_contact", move |contact: Contact| -> Result<Contact, Box<EvalAltResult>> {
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        let result = db_clone_set_contact.set(&contact)
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error set_contact: {}", e).into(), Position::NONE)))?;
 | 
			
		||||
        
 | 
			
		||||
        // Return the updated contact with the correct ID
 | 
			
		||||
        Ok(result.1)
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Manually register database functions as they need to capture 'db'
 | 
			
		||||
    let db_clone_delete_contact = db.clone();
 | 
			
		||||
    db_module.set_native_fn("delete_contact", move |contact: Contact| -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        let result = db_clone_delete_contact.collection::<Contact>()
 | 
			
		||||
            .expect("can open contact collection")
 | 
			
		||||
            .delete_by_id(contact.base_data.id)
 | 
			
		||||
            .expect("can delete event");
 | 
			
		||||
        
 | 
			
		||||
        // Return the updated event with the correct ID
 | 
			
		||||
        Ok(result)
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    let db_clone_get_contact = db.clone();
 | 
			
		||||
    db_module.set_native_fn("get_contact_by_id", move |id_i64: INT| -> Result<Contact, Box<EvalAltResult>> {
 | 
			
		||||
        let id_u32 = id_from_i64_to_u32(id_i64)?;
 | 
			
		||||
        // Use the Collection trait method directly
 | 
			
		||||
        db_clone_get_contact.get_by_id(id_u32)
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error get_contact_by_id: {}", e).into(), Position::NONE)))?            
 | 
			
		||||
            .ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Contact with ID {} not found", id_u32).into(), Position::NONE)))
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Add list_contacts function to get all contacts
 | 
			
		||||
    let db_clone_list_contacts = db.clone();
 | 
			
		||||
    db_module.set_native_fn("list_contacts", move || -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
        let collection = db_clone_list_contacts.collection::<Contact>()
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
                format!("Failed to get contact collection: {:?}", e).into(), 
 | 
			
		||||
                Position::NONE
 | 
			
		||||
            )))?;
 | 
			
		||||
        let contacts = collection.get_all()
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
                format!("Failed to get all contacts: {:?}", e).into(), 
 | 
			
		||||
                Position::NONE
 | 
			
		||||
            )))?;
 | 
			
		||||
        let mut array = Array::new();
 | 
			
		||||
        for contact in contacts {
 | 
			
		||||
            array.push(Dynamic::from(contact));
 | 
			
		||||
        }
 | 
			
		||||
        Ok(Dynamic::from(array))
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    // Add list_events function to get all events
 | 
			
		||||
    let db_clone_list_groups = db.clone();
 | 
			
		||||
    db_module.set_native_fn("list_groups", move || -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
        let collection = db_clone_list_groups.collection::<Group>()
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
                format!("Failed to get group collection: {:?}", e).into(), 
 | 
			
		||||
                Position::NONE
 | 
			
		||||
            )))?;
 | 
			
		||||
        let groups = collection.get_all()
 | 
			
		||||
            .map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
                format!("Failed to get all groups: {:?}", e).into(), 
 | 
			
		||||
                Position::NONE
 | 
			
		||||
            )))?;
 | 
			
		||||
        let mut array = Array::new();
 | 
			
		||||
        for group in groups {
 | 
			
		||||
            array.push(Dynamic::from(group));
 | 
			
		||||
        }
 | 
			
		||||
        Ok(Dynamic::from(array))
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Register the database module globally
 | 
			
		||||
    engine.register_global_module(db_module.into());
 | 
			
		||||
 | 
			
		||||
    println!("Successfully registered contact Rhai module using export_module approach.");
 | 
			
		||||
}
 | 
			
		||||
@@ -2,7 +2,9 @@
 | 
			
		||||
pub mod core;
 | 
			
		||||
pub mod userexample;
 | 
			
		||||
// pub mod productexample; // Temporarily remove as files are missing
 | 
			
		||||
pub mod access;
 | 
			
		||||
pub mod calendar;
 | 
			
		||||
pub mod contact;
 | 
			
		||||
pub mod circle;
 | 
			
		||||
pub mod governance;
 | 
			
		||||
pub mod finance;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user