add heroledger models
This commit is contained in:
@@ -10,8 +10,8 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
bincode = { version = "2", features = ["serde"] }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
ourdb = { path = "../ourdb" }
|
||||
tst = { path = "../tst" }
|
||||
ourdb = { path = "../../herolib_rust/packages/data/ourdb" }
|
||||
tst = { path = "../../herolib_rust/packages/data/tst" }
|
||||
heromodels-derive = { path = "../heromodels-derive" }
|
||||
heromodels_core = { path = "../heromodels_core" }
|
||||
rhai = { version = "1.21.0", features = [
|
||||
|
@@ -52,7 +52,6 @@ pub mut:
|
||||
use heromodels_core::{Model, BaseModelData, IndexKey};
|
||||
use heromodels_derive::model;
|
||||
use rhai::CustomType;
|
||||
use rhailib_derive::RhaiApi;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use chrono::{DateTime, Utc};
|
||||
```
|
||||
|
53
heromodels/examples/heroledger/heroledger.rhai
Normal file
53
heromodels/examples/heroledger/heroledger.rhai
Normal file
@@ -0,0 +1,53 @@
|
||||
// heroledger.rhai - Demonstration of HeroLedger models in Rhai
|
||||
|
||||
print("=== HeroLedger Models Demo ===");
|
||||
|
||||
// Create a new user
|
||||
print("\n--- Creating User ---");
|
||||
let new_user = new_user()
|
||||
.name("Alice Johnson")
|
||||
.email("alice@herocode.com")
|
||||
.pubkey("0x1234567890abcdef")
|
||||
.status("Active")
|
||||
.save_user();
|
||||
|
||||
print("Created user: " + new_user.get_name());
|
||||
print("User ID: " + new_user.get_id());
|
||||
print("User email: " + new_user.get_email());
|
||||
print("User pubkey: " + new_user.get_pubkey());
|
||||
|
||||
// Create a new group
|
||||
print("\n--- Creating Group ---");
|
||||
let new_group = new_group()
|
||||
.name("HeroCode Developers")
|
||||
.description("A group for HeroCode development team members")
|
||||
.visibility("Public")
|
||||
.save_group();
|
||||
|
||||
print("Created group: " + new_group.get_name());
|
||||
print("Group ID: " + new_group.get_id());
|
||||
print("Group description: " + new_group.get_description());
|
||||
|
||||
// Create a new account
|
||||
print("\n--- Creating Account ---");
|
||||
let new_account = new_account()
|
||||
.name("Alice's Main Account")
|
||||
.description("Primary account for Alice Johnson")
|
||||
.currency("USD")
|
||||
.save_account();
|
||||
|
||||
print("Created account: " + new_account.get_name());
|
||||
print("Account ID: " + new_account.get_id());
|
||||
print("Account currency: " + new_account.get_currency());
|
||||
|
||||
// Create a new DNS zone
|
||||
print("\n--- Creating DNS Zone ---");
|
||||
let new_dns_zone = new_dns_zone()
|
||||
.name("herocode.com")
|
||||
.description("Main domain for HeroCode")
|
||||
.save_dns_zone();
|
||||
|
||||
print("Created DNS zone: " + new_dns_zone.get_name());
|
||||
print("DNS zone ID: " + new_dns_zone.get_id());
|
||||
|
||||
print("\n=== Demo Complete ===");
|
50
heromodels/examples/heroledger/main.rs
Normal file
50
heromodels/examples/heroledger/main.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
use heromodels_core::db::hero::OurDB;
|
||||
use rhai::{Dynamic, Engine};
|
||||
use heromodels::models::heroledger::rhai::register_heroledger_rhai_modules;
|
||||
use std::sync::Arc;
|
||||
use std::{fs, path::Path};
|
||||
|
||||
const CALLER_ID: &str = "example_caller";
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Initialize Rhai engine
|
||||
let mut engine = Engine::new();
|
||||
|
||||
// Initialize database with OurDB
|
||||
let db_path = "temp_heroledger_db";
|
||||
// Clean up previous database file if it exists
|
||||
if Path::new(db_path).exists() {
|
||||
fs::remove_dir_all(db_path)?;
|
||||
}
|
||||
let _db = Arc::new(OurDB::new(db_path, true).expect("Failed to create database"));
|
||||
|
||||
// Register the heroledger modules with Rhai
|
||||
register_heroledger_rhai_modules(&mut engine);
|
||||
|
||||
let mut db_config = rhai::Map::new();
|
||||
db_config.insert("DB_PATH".into(), db_path.into());
|
||||
db_config.insert("CALLER_ID".into(), CALLER_ID.into());
|
||||
db_config.insert("CONTEXT_ID".into(), CALLER_ID.into());
|
||||
engine.set_default_tag(Dynamic::from(db_config)); // Or pass via CallFnOptions
|
||||
|
||||
// Load and evaluate the Rhai script
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let script_path = Path::new(manifest_dir)
|
||||
.join("examples")
|
||||
.join("heroledger")
|
||||
.join("heroledger.rhai");
|
||||
println!("Script path: {}", script_path.display());
|
||||
let script = fs::read_to_string(&script_path)?;
|
||||
|
||||
println!("--- Running HeroLedger Rhai Script ---");
|
||||
match engine.eval::<()>(&script) {
|
||||
Ok(_) => println!("\n--- Script executed successfully! ---"),
|
||||
Err(e) => eprintln!("\n--- Script execution failed: {} ---", e),
|
||||
}
|
||||
|
||||
// Clean up the database file
|
||||
fs::remove_dir_all(db_path)?;
|
||||
println!("--- Cleaned up temporary database. ---");
|
||||
|
||||
Ok(())
|
||||
}
|
@@ -7,6 +7,7 @@ pub mod dnsrecord;
|
||||
pub mod secretbox;
|
||||
pub mod signature;
|
||||
pub mod user_kvs;
|
||||
pub mod rhai;
|
||||
|
||||
// Re-export key types for convenience
|
||||
pub use user::{User, UserStatus, UserProfile, KYCInfo, KYCStatus, SecretBox};
|
||||
|
330
heromodels/src/models/heroledger/rhai.rs
Normal file
330
heromodels/src/models/heroledger/rhai.rs
Normal file
@@ -0,0 +1,330 @@
|
||||
use ::rhai::plugin::*;
|
||||
use ::rhai::{Array, Dynamic, Engine, EvalAltResult, Map, Module};
|
||||
use std::mem;
|
||||
|
||||
use crate::models::heroledger::*;
|
||||
|
||||
// ============================================================================
|
||||
// User Module
|
||||
// ============================================================================
|
||||
|
||||
type RhaiUser = User;
|
||||
|
||||
#[export_module]
|
||||
mod rhai_user_module {
|
||||
use super::RhaiUser;
|
||||
|
||||
#[rhai_fn(name = "new_user", return_raw)]
|
||||
pub fn new_user() -> Result<RhaiUser, Box<EvalAltResult>> {
|
||||
Ok(User::new(0))
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "username", return_raw)]
|
||||
pub fn set_username(
|
||||
user: &mut RhaiUser,
|
||||
username: String,
|
||||
) -> Result<RhaiUser, Box<EvalAltResult>> {
|
||||
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<RhaiUser, Box<EvalAltResult>> {
|
||||
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<RhaiUser, Box<EvalAltResult>> {
|
||||
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<RhaiUser, Box<EvalAltResult>> {
|
||||
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<RhaiUser, Box<EvalAltResult>> {
|
||||
// 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) -> i64 {
|
||||
user.base_data.id as i64
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "get_username")]
|
||||
pub fn get_username(user: &mut RhaiUser) -> String {
|
||||
user.username.clone().unwrap_or_else(|| String::new())
|
||||
}
|
||||
|
||||
#[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().unwrap_or_else(|| String::new())
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 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<RhaiGroup, Box<EvalAltResult>> {
|
||||
Ok(Group::new(0))
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "name", return_raw)]
|
||||
pub fn set_name(
|
||||
group: &mut RhaiGroup,
|
||||
name: String,
|
||||
) -> Result<RhaiGroup, Box<EvalAltResult>> {
|
||||
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<RhaiGroup, Box<EvalAltResult>> {
|
||||
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<RhaiGroup, Box<EvalAltResult>> {
|
||||
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<RhaiGroup, Box<EvalAltResult>> {
|
||||
Ok(group.clone())
|
||||
}
|
||||
|
||||
// Getters
|
||||
#[rhai_fn(name = "get_id")]
|
||||
pub fn get_id(group: &mut RhaiGroup) -> i64 {
|
||||
group.base_data.id as i64
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "get_name")]
|
||||
pub fn get_name(group: &mut RhaiGroup) -> String {
|
||||
group.name.clone().unwrap_or_else(|| String::new())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "get_description")]
|
||||
pub fn get_description(group: &mut RhaiGroup) -> String {
|
||||
group.description.clone().unwrap_or_else(|| String::new())
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 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<RhaiAccount, Box<EvalAltResult>> {
|
||||
Ok(Account::new(0))
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "owner_id", return_raw)]
|
||||
pub fn set_owner_id(
|
||||
account: &mut RhaiAccount,
|
||||
owner_id: i64,
|
||||
) -> Result<RhaiAccount, Box<EvalAltResult>> {
|
||||
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<RhaiAccount, Box<EvalAltResult>> {
|
||||
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<RhaiAccount, Box<EvalAltResult>> {
|
||||
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<RhaiAccount, Box<EvalAltResult>> {
|
||||
Ok(account.clone())
|
||||
}
|
||||
|
||||
// Getters
|
||||
#[rhai_fn(name = "get_id")]
|
||||
pub fn get_id(account: &mut RhaiAccount) -> i64 {
|
||||
account.base_data.id as i64
|
||||
}
|
||||
|
||||
#[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<RhaiDNSZone, Box<EvalAltResult>> {
|
||||
Ok(DNSZone::new(0))
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "name", return_raw)]
|
||||
pub fn set_name(
|
||||
zone: &mut RhaiDNSZone,
|
||||
name: String,
|
||||
) -> Result<RhaiDNSZone, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(zone);
|
||||
*zone = owned.name(name);
|
||||
Ok(zone.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "description", return_raw)]
|
||||
pub fn set_description(
|
||||
zone: &mut RhaiDNSZone,
|
||||
description: String,
|
||||
) -> Result<RhaiDNSZone, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(zone);
|
||||
*zone = owned.description(description);
|
||||
Ok(zone.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "save_dns_zone", return_raw)]
|
||||
pub fn save_dns_zone(zone: &mut RhaiDNSZone) -> Result<RhaiDNSZone, Box<EvalAltResult>> {
|
||||
Ok(zone.clone())
|
||||
}
|
||||
|
||||
// Setters
|
||||
#[rhai_fn(name = "set_domain")]
|
||||
pub fn set_domain(zone: &mut RhaiDNSZone, domain: &str) {
|
||||
let owned = std::mem::take(zone);
|
||||
*zone = owned.domain(domain);
|
||||
}
|
||||
|
||||
// Getters
|
||||
#[rhai_fn(name = "get_id")]
|
||||
pub fn get_id(zone: &mut RhaiDNSZone) -> i64 {
|
||||
zone.base_data.id as i64
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "get_domain")]
|
||||
pub fn get_domain(zone: &mut RhaiDNSZone) -> String {
|
||||
zone.domain.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Registration Functions
|
||||
// ============================================================================
|
||||
// Registration functions
|
||||
pub fn register_user_functions(engine: &mut Engine) {
|
||||
let module = exported_module!(user_module);
|
||||
engine.register_static_module("user", module.into());
|
||||
}
|
||||
|
||||
pub fn register_group_functions(engine: &mut Engine) {
|
||||
let module = exported_module!(group_module);
|
||||
engine.register_static_module("group", module.into());
|
||||
}
|
||||
|
||||
pub fn register_account_functions(engine: &mut Engine) {
|
||||
let module = exported_module!(account_module);
|
||||
engine.register_static_module("account", module.into());
|
||||
}
|
||||
|
||||
pub fn register_dnszone_functions(engine: &mut Engine) {
|
||||
let module = exported_module!(dnszone_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);
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
// Export contact module
|
||||
// Export object module
|
||||
pub mod object;
|
||||
pub mod object_rhai_dsl;
|
||||
|
||||
// Re-export contact, Group from the inner contact module (contact.rs) within src/models/contact/mod.rs
|
||||
// Re-export Object from the inner object module (object.rs) within src/models/object/mod.rs
|
||||
pub use self::object::Object;
|
||||
|
56
heromodels/src/models/object/object_rhai_dsl.rs
Normal file
56
heromodels/src/models/object/object_rhai_dsl.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
use rhai::plugin::*;
|
||||
use rhai::{CustomType, Dynamic, Engine, EvalAltResult, Module};
|
||||
use super::Object;
|
||||
|
||||
type RhaiObject = Object;
|
||||
|
||||
#[export_module]
|
||||
pub mod generated_rhai_module {
|
||||
use super::*;
|
||||
|
||||
/// Create a new Object
|
||||
#[rhai_fn(name = "new_object")]
|
||||
pub fn new_object() -> RhaiObject {
|
||||
Object::new()
|
||||
}
|
||||
|
||||
/// Set the title of an Object
|
||||
#[rhai_fn(name = "object_title")]
|
||||
pub fn object_title(
|
||||
object: &mut RhaiObject,
|
||||
title: String,
|
||||
) -> RhaiObject {
|
||||
let mut result = object.clone();
|
||||
result.title = title;
|
||||
result
|
||||
}
|
||||
|
||||
/// Set the description of an Object
|
||||
#[rhai_fn(name = "object_description")]
|
||||
pub fn object_description(
|
||||
object: &mut RhaiObject,
|
||||
description: String,
|
||||
) -> RhaiObject {
|
||||
let mut result = object.clone();
|
||||
result.description = description;
|
||||
result
|
||||
}
|
||||
|
||||
/// Get the ID of an Object
|
||||
#[rhai_fn(name = "get_object_id")]
|
||||
pub fn get_object_id(object: &mut RhaiObject) -> i64 {
|
||||
object.id() as i64
|
||||
}
|
||||
|
||||
/// Get the title of an Object
|
||||
#[rhai_fn(name = "get_object_title")]
|
||||
pub fn get_object_title(object: &mut RhaiObject) -> String {
|
||||
object.title.clone()
|
||||
}
|
||||
|
||||
/// Get the description of an Object
|
||||
#[rhai_fn(name = "get_object_description")]
|
||||
pub fn get_object_description(object: &mut RhaiObject) -> String {
|
||||
object.description.clone()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user