use ::rhai::plugin::*; use ::rhai::{Dynamic, Engine, EvalAltResult, Module, CustomType, TypeBuilder}; use std::mem; use crate::objects::heroledger::{ dnsrecord::DNSZone, group::{Group, Visibility}, money::Account, user::{User, UserStatus}, }; // ============================================================================ // User Module // ============================================================================ type RhaiUser = User; #[export_module] mod rhai_user_module { use crate::objects::heroledger::user::User; use super::RhaiUser; #[rhai_fn(name = "new_user", return_raw)] pub fn new_user() -> Result> { Ok(User::new(0)) } #[rhai_fn(name = "username", return_raw)] pub fn set_username( user: &mut RhaiUser, username: String, ) -> Result> { let owned = std::mem::take(user); *user = owned.username(username); Ok(user.clone()) } #[rhai_fn(name = "add_email", return_raw)] pub fn add_email(user: &mut RhaiUser, email: String) -> Result> { let owned = std::mem::take(user); *user = owned.add_email(email); Ok(user.clone()) } #[rhai_fn(name = "pubkey", return_raw)] pub fn set_pubkey(user: &mut RhaiUser, pubkey: String) -> Result> { let owned = std::mem::take(user); *user = owned.pubkey(pubkey); Ok(user.clone()) } #[rhai_fn(name = "status", return_raw)] pub fn set_status(user: &mut RhaiUser, status: String) -> Result> { let status_enum = match status.as_str() { "Active" => UserStatus::Active, "Inactive" => UserStatus::Inactive, "Suspended" => UserStatus::Suspended, "Archived" => UserStatus::Archived, _ => return Err(format!("Invalid user status: {}", status).into()), }; let owned = std::mem::take(user); *user = owned.status(status_enum); Ok(user.clone()) } #[rhai_fn(name = "save_user", return_raw)] pub fn save_user(user: &mut RhaiUser) -> Result> { // This would integrate with the database save functionality // For now, just return the user as-is Ok(user.clone()) } // Getters #[rhai_fn(name = "get_id")] pub fn get_id(user: &mut RhaiUser) -> u32 { user.base_data.id } #[rhai_fn(name = "get_username")] pub fn get_username(user: &mut RhaiUser) -> String { user.username.clone() } #[rhai_fn(name = "get_email")] pub fn get_email(user: &mut RhaiUser) -> String { if let Some(first_email) = user.email.first() { first_email.clone() } else { String::new() } } #[rhai_fn(name = "get_pubkey")] pub fn get_pubkey(user: &mut RhaiUser) -> String { user.pubkey.clone() } } // ============================================================================ // Group Module // ============================================================================ type RhaiGroup = Group; #[export_module] mod rhai_group_module { use super::RhaiGroup; #[rhai_fn(name = "new_group", return_raw)] pub fn new_group() -> Result> { Ok(Group::new(0)) } #[rhai_fn(name = "name", return_raw)] pub fn set_name(group: &mut RhaiGroup, name: String) -> Result> { let owned = std::mem::take(group); *group = owned.name(name); Ok(group.clone()) } #[rhai_fn(name = "description", return_raw)] pub fn set_description( group: &mut RhaiGroup, description: String, ) -> Result> { let owned = std::mem::take(group); *group = owned.description(description); Ok(group.clone()) } #[rhai_fn(name = "visibility", return_raw)] pub fn set_visibility( group: &mut RhaiGroup, visibility: String, ) -> Result> { let visibility_enum = match visibility.as_str() { "Public" => Visibility::Public, "Private" => Visibility::Private, _ => return Err(format!("Invalid visibility: {}", visibility).into()), }; let owned = std::mem::take(group); *group = owned.visibility(visibility_enum); Ok(group.clone()) } #[rhai_fn(name = "save_group", return_raw)] pub fn save_group(group: &mut RhaiGroup) -> Result> { Ok(group.clone()) } // Getters #[rhai_fn(name = "get_id")] pub fn get_id(group: &mut RhaiGroup) -> u32 { group.base_data.id } #[rhai_fn(name = "get_name")] pub fn get_name(group: &mut RhaiGroup) -> String { group.name.clone() } #[rhai_fn(name = "get_description")] pub fn get_description(group: &mut RhaiGroup) -> String { group.description.clone() } } // ============================================================================ // Account Module (from money.rs) // ============================================================================ type RhaiAccount = Account; #[export_module] mod rhai_account_module { use super::RhaiAccount; #[rhai_fn(name = "new_account", return_raw)] pub fn new_account() -> Result> { Ok(Account::new(0)) } #[rhai_fn(name = "owner_id", return_raw)] pub fn set_owner_id( account: &mut RhaiAccount, owner_id: i64, ) -> Result> { let owned = std::mem::take(account); *account = owned.owner_id(owner_id as u32); Ok(account.clone()) } #[rhai_fn(name = "address", return_raw)] pub fn set_address( account: &mut RhaiAccount, address: String, ) -> Result> { let owned = std::mem::take(account); *account = owned.address(address); Ok(account.clone()) } #[rhai_fn(name = "currency", return_raw)] pub fn set_currency( account: &mut RhaiAccount, currency: String, ) -> Result> { let owned = std::mem::take(account); *account = owned.currency(currency); Ok(account.clone()) } #[rhai_fn(name = "save_account", return_raw)] pub fn save_account(account: &mut RhaiAccount) -> Result> { Ok(account.clone()) } // Getters #[rhai_fn(name = "get_id")] pub fn get_id(account: &mut RhaiAccount) -> u32 { account.base_data.id } #[rhai_fn(name = "get_address")] pub fn get_address(account: &mut RhaiAccount) -> String { account.address.clone() } #[rhai_fn(name = "get_currency")] pub fn get_currency(account: &mut RhaiAccount) -> String { account.currency.clone() } } // ============================================================================ // DNS Zone Module // ============================================================================ type RhaiDNSZone = DNSZone; #[export_module] mod rhai_dns_zone_module { use super::RhaiDNSZone; #[rhai_fn(name = "new_dns_zone", return_raw)] pub fn new_dns_zone() -> Result> { Ok(DNSZone::new(0)) } #[rhai_fn(name = "domain", return_raw)] pub fn set_domain( zone: &mut RhaiDNSZone, domain: String, ) -> Result> { let owned = std::mem::take(zone); *zone = owned.domain(domain); Ok(zone.clone()) } #[rhai_fn(name = "save_dns_zone", return_raw)] pub fn save_dns_zone(zone: &mut RhaiDNSZone) -> Result> { Ok(zone.clone()) } // Getters #[rhai_fn(name = "get_id")] pub fn get_id(zone: &mut RhaiDNSZone) -> u32 { zone.base_data.id } #[rhai_fn(name = "get_domain")] pub fn get_domain(zone: &mut RhaiDNSZone) -> String { zone.domain.clone() } } // ============================================================================ // Registration Functions // ============================================================================ // Registration functions /// Register heroledger modules into a Rhai Module (for use in packages) /// This flattens all functions into the parent module pub fn register_heroledger_modules(parent_module: &mut Module) { // Register custom types parent_module.set_custom_type::("User"); parent_module.set_custom_type::("Group"); parent_module.set_custom_type::("Account"); parent_module.set_custom_type::("DNSZone"); // Merge user functions into parent module let user_module = exported_module!(rhai_user_module); parent_module.merge(&user_module); // Merge group functions into parent module let group_module = exported_module!(rhai_group_module); parent_module.merge(&group_module); // Merge account functions into parent module let account_module = exported_module!(rhai_account_module); parent_module.merge(&account_module); // Merge dnszone functions into parent module let dnszone_module = exported_module!(rhai_dns_zone_module); parent_module.merge(&dnszone_module); } /// Register heroledger modules into a Rhai Engine (for standalone use) pub fn register_user_functions(engine: &mut Engine) { let module = exported_module!(rhai_user_module); engine.register_static_module("user", module.into()); } pub fn register_group_functions(engine: &mut Engine) { let module = exported_module!(rhai_group_module); engine.register_static_module("group", module.into()); } pub fn register_account_functions(engine: &mut Engine) { let module = exported_module!(rhai_account_module); engine.register_static_module("account", module.into()); } pub fn register_dnszone_functions(engine: &mut Engine) { let module = exported_module!(rhai_dns_zone_module); engine.register_static_module("dnszone", module.into()); } /// Register all heroledger Rhai modules with the engine pub fn register_heroledger_rhai_modules(engine: &mut Engine) { register_user_functions(engine); register_group_functions(engine); register_account_functions(engine); register_dnszone_functions(engine); } // ============================================================================ // CustomType Implementations (for type registration in Rhai) // ============================================================================ impl CustomType for User { fn build(mut builder: TypeBuilder) { builder.with_name("User"); } } impl CustomType for Group { fn build(mut builder: TypeBuilder) { builder.with_name("Group"); } } impl CustomType for Account { fn build(mut builder: TypeBuilder) { builder.with_name("Account"); } } impl CustomType for DNSZone { fn build(mut builder: TypeBuilder) { builder.with_name("DNSZone"); } }